Lập trình Promise với BlueBird qua ví dụ - Phần 1
Lập trình Promise với BlueBird qua ví dụ - Phần 2
Lập trình Promise với BlueBird - Phần 3: Map

Trong bài này chúng ta sẽ phân biệt giữa then và spread.
then
.then([Function fulfilledHandler] [, Function rejectedHandler ]) -> Promise

Promises/A+ .then(). Returns a new promise chained from this promise. The new promise will be rejected or resolved depending on the passed fulfilledHandler, rejectedHandler and the state of this promise.
.then() trả về một promise mới tiếp nối vào promise hiện thời. Promise mới sẽ bị từ chối (rejected) hay xử lý (resolved) phụ thuộc vào tham số hàm chuyền vào fulfilledHandler, rejectedHandler và trạng thái của promise hiện giờ.

spread
.spread([Function fulfilledHandler] [, Function rejectedHandler ]) -> Promise

Like calling .then, but the fulfillment value or rejection reason must be an array, which is flattened to the formal parameters of the handlers.
Ở spread, Promise mới được trả về sẽ nhận mảng giá trị thành công (fullfillment) hoặc mảng đối tượng lỗi (error) do Promise hiện tại trả về dưới dạng dãy các tham số.

Ví dụ dưới đây so sánh nội dung của 2 file. Hai file có kích thước lớn nhỏ khác nhau, thời gian đọc từ ổ cứng sẽ khác nhau. Ứng dụng sẽ chờ 2 tác vụ này thành công (fullfilled) để xử lý trong spread. Nếu 1 trong hai tác vụ thất bại (rejected) thì hàm cach sẽ xử lý lỗi trả về.
Phía trước trả về mảng 2 Promise return [readFileAsync("fileA.json"), readFileAsync("fileB.json")];
Thì ta phải truyền 2 tham số vào spread để xử lý kết quả fullfillment trả về từ 2 Promise ở trên.

var promise = require('bluebird');
var readFileAsync = promise.promisify(require('fs').readFile);
promise.resolve().then(function() {
    return [readFileAsync("fileA.json"),
        readFileAsync("fileB.json")] ;
}).spread(function(file1text, file2text) { //Nếu cả 2 tác vụ đọc đều thành công thì so sánh
    if (file1text === file2text) {
        console.log("files are equal");
    } else {
        console.log("files are not equal");
    }
}).catch(function(err){  //Xử lý lỗi
    console.log(err.message);

});

Kết luận

  1. Khi trả về nhiều hơn một promise, bắt buộc phải dùng spread, chứ không thể dùng then
  2. Hàm xử lý fullfillment trong spread chỉ được thực thi khi tất cả các promise trước đó đều thành công
  3. Chỉ cần một promise phía trước thất bại, cach(function(err)) sẽ được gọi