any vs race vs some

map vs each

  • map chạy đồng thời các promise
  • any chạy tuần tự các promise. promise trước phải hoàn thành hoặc thất bại mới chạy tiếp promise kế tiếp.

Ví dụ minh họa tính tuần tự của each và đồng thời của map

var Promise = require("bluebird");
function doTask(task){
    return new Promise(function(fulfill, reject) {
        setTimeout(function(){
            fulfill(task);
        }, 2000);
    });
}
function now(txt) {
    console.log(new Date().toLocaleTimeString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}

var tasks = ['task A', 'task B'];
now('start');
Promise.each(tasks, function(task){  //Chú ý thay each bằng map ở đây
    return doTask(task).then(function(result) {
        now(result);  //In ra thời điểm và kết quả khi từng tác vụ thành công. Thứ tự sẽ khác với thứ tự các phần tử mảng
        return result;
    }).catch(function(err){
        console.log('error: ', err.message);
    });

});

task B chạy cách task A 2 giây do phải đợi

00:25:25 start
00:25:27 task A
00:25:29 task B

Đổi lại sang map, task B chạy gần như đồng thời với task A

00:27:22 start
00:27:24 task A
00:27:24 task B

Ví dụ thêm về each, tải ảnh trên mạng

var fs = require('fs');
var Promise = require("bluebird");
var request = require('request');
var photoLinks = [{link: 'https://unsplash.imgix.net/photo-1425235024244-b0e56d3cf907?fit=crop&fm=jpg&h=700&q=75&w=1050',
    name: 'dog.jpg'},
    {link: 'https://unsplash.imgix.net/reserve/NxxLccbqQdGtNc7xJ43e_ancestral-home.jpg?fit=crop&fm=jpg&h=600&q=75&w=1050',
        name: 'house.jpg'},
    {link: 'https://unsplash.imgix.net/photo-1423439793616-f2aa4356b37e?q=75&fm=jpg&s=3b42f9c018b2712544debf4d6a4998ff',
        name: 'car.jpg'},
    {link: 'https://techmaster.vn', name: 'bad.jpg'}, //cố tình tạo một phần tử có lỗi ở đây
    {link: 'https://unsplash.imgix.net/photo-1422513391413-ddd4f2ce3340?q=75&fm=jpg&s=282e5978de17d6cd2280888d16f06f04',
        name: 'nightstar.jpg'}

];
function now(txt) {
    console.log(new Date().toLocaleTimeString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}

function getPhoto(photoLink){
    return new Promise(function(fulfill, reject) {
        request.get(photoLink.link)
            .on('error', function (err) {
                err.photo = photoLink.link;
                reject(err);
            })
            .pipe(fs.createWriteStream(photoLink.name)
                .on('finish', function () {
                    fulfill(photoLink.name);
                }).on('error', function (err) {
                    reject(err);
                })
        );
    });
}

function now(txt) {
    console.log(new Date().toLocaleTimeString().replace(/T/, ' ').replace(/\..+/, '')+' '+txt);
}
console.time("getPhoto");
Promise.each(photoLinks, function(item){
    return getPhoto(item).then(function(result) {
        now(result);  //In ra thời điểm và kết quả khi từng tác vụ thành công. Thứ tự sẽ khác với thứ tự các phần tử mảng
        return result;
    }).catch(function(err){
        console.log('error: ', err.message);
    });
}).then(function(finalResult){
    console.timeEnd("getPhoto");
});

Kết quả trả về

00:00:08 dog.jpg
00:00:10 house.jpg
00:00:12 car.jpg
error:  connect ECONNREFUSED 103.27.238.52:443
00:00:14 nightstar.jpg
getPhoto: 7165ms