+12

Node.js Tutorial: Phần 3 - Promise trong Nodejs

Asynchronous trong Javascript

Asynchronous là xử lý bất động bộ, nghĩa là chương trình có thể nhảy đi bỏ qua một bước nào đó, nó làm cho ứng dụng hoạt động không chặt chẽ và không có quy trình nên việc quản lý rất khó khăn. Ví dụ trong một chuỗi các hàm, sự bất đồng bộ có nghĩa là cho dù hàm B được gọi sau hàm A nhưng không ai đảm bảo được rằng hàm A sẽ phải kết thúc trước hàm B và hàm B bắt buộc phải chỉ được gọi chạy khi hàm A kết thúc. Trong Javascript, để gọi một async function chúng ta thường sử dụng đến callback, tuy nhiên có một vấn đề cực kỳ nhức nhối đã được thể hiện với callback của javascript, đó là callback hell, ví dụ như sau:

getData(function(a){  
    getMoreData(a, function(b){
        getMoreData(b, function(c){ 
            getMoreData(c, function(d){ 
                getMoreData(d, function(e){ 
                    ...
                });
            });
        });
    });
});

Vì sao nên dùng Promise thay cho callback ?

Promise là một giải pháp giúp bạn xử lý các hàm asynchronous một cách tốt hơn. Promise được sinh ra để thể hiện cho kết quả sau cùng của một tác vụ bất đồng bộ. Nếu so sánh với các phướng thức callback truyền thống thì promise cung cấp một biện pháp thay thế đơn giản hơn trong việc thực thi, biên soạn và quản lý các tác vụ bất đồng bộ. Ngoài ra promise còn cho phép chúng ta handle các lỗi xảy ra khi thực thi tác vụ bất đồng bằng các sử dụng các phương thức tiếp cận tương tự với sử dụng try/catch trong các tác vụ đồng bộ (synchronous) thông thường.

Cách dùng Promise trong Nodejs

Để sử dụng Promise trong Nodejs, thường thì các bạn cần cài thêm một module như Q hoặc Bluebird để viết Promise. Bài viết này mình sẽ sử dụng Q module nhé. Cài đặt Q bằng npm: npm install q --save. Để sử dụng q module trong project bằng cách khai báo: var Q = require("q");

Sử dụng Q.fcall

Bạn có thể sử dụng Q.fcall để tạo ra một Promise từ một hàm trả về một giá trị cố định.

var promise = Q.fcall(function () {
    return "Fixed value";
});

promise.then(function(data) {
    console.log(data);
}, function(error) {
     console.log(error);
});

Sử dụng Q Deferreds

var promise = function (check) {
    var deferred = Q.defer();
    if (check) {
        deferred.resolve("Resolve it"); 
    } else {
        deferred.reject("Error");
    }
    
    return deferred.promise;
}; 

promise.then(function(data) {
    console.log(data);
}, function(error) {
     console.log(error);
});

Sử dụng Q.Promise

var promise = function(check) {
    return Q.promise(function(resolve, reject,) {
        if (check) {
            resolve("Resolve it"); 
        } else {
            reject("Error");
        }
    });
};

promise.then(function(data) {
    console.log(data);
}, function(error) {
     console.log(error);
});

Nối nhiều Promise

Function của bạn có nhiều xử lý bất đồng bộ cần xử lý, khi một xử lý kết thúc trả về dữ liệu sẽ bắt đầu một xử lý bất đồng bộ khác. Để xử lý trường hợp này bạn có thể sử dụng nối nhiều Promise như sau:

promise
.then(function(data1) {
    return data2;
})
.then(function(data2) {
    // kết quả promise vừa trả về ở trên.
});

Xử lý lỗi

promise.then(function(data) {
}).catch(function(error) {
  console.log('Error');
});

Kết luận

Có rất nhiều cách để bạn sử dụng promise trong Nodejs, đây là cách tốt nhất để bạn tránh được callback hell và làm cho code của bạn sẽ trở nên sáng sủa, dễ hiểu, dễ maintain hơn cũng như nguy hiểm hơn =))

Tham khảo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí