+2

Tìm hiểu Promise trong 5 phút

1. Nội dung

Bài viết này sẽ giới thiệu cho bạn những điều cơ bản về Promise trong JavaScript. Đây không phải là một bài viết bao gồm tất cả, nhưng thay vào đó sẽ cung cấp cho bạn kiến thức cơ bản mà bạn cần phải hiểu và bắt đầu sử dụng Promise trong source code của bạn.

2. Tại sao chúng ta cần Promise

Promise (giống như callbacks) cho phép chúng ta chờ đợi một đoạn code phải hoàn thành, trước khi chạy đoạn code tiếp theo.

Tại sao nó lại quan trọng ư? Bạn hãy tưởng tượng về một trang web tải dữ liệu từ một API, sau đó xử lý và định dạng dữ liệu để hiển thị cho người dùng. Nếu chúng ta thực hiện xử lý và định dạng dữ liệu trước khi API tìm nạp thông tin, chúng ta chắc chắn sẽ gặp lỗi hoặc sẽ thành một trang web trống. Bằng cách sử dụng Promise, chúng ta có thể đảm bảo rằng dữ liệu API không được xử lý / định dạng cho đến khi việc gọi API đã thành công.

3. Promise là gì?

Trong JavaScript, Promise thể hiện kết quả cuối cùng của một tiến trình không đồng bộ. Hãy nghĩ về nó như một placeholder. Placeholder này về bản chất là một đối tượng mà trên đó chúng ta có thể đính kèm các callback.

Promise có thể có một trong ba trạng thái:

Pending - Thao tác không đồng bộ chưa hoàn thành

Fulfilled - Hoạt động đã hoàn thành và Promise có giá trị

Rejected - Thao tác đã hoàn thành với lỗi hoặc không thành công.

Promise sẽ được giải quyết nếu nó không ở trạng thái pending. Khi Promise đã ổn định, nó được giải quyết tốt. Nó không thể chuyển sang bất kỳ trạng thái nào khác

4. Làm việc với Promise

Hầu hết thời gian khi làm việc với Promises, bạn sẽ sử dụng những Promise đã được tạo ra và được trả về từ các hàm. Tuy nhiên, bạn cũng có thể tạo Promise với hàm tạo của nó.

Dưới đây là Promise đơn giản giống như này:

runFunction().then(successFunc, failureFunc);

Với ví dụ trên, trước tiên chúng ta gọi hàm runFunction(). Vì hàm runFunction() trả về một Promise, chỉ khi Promise hoàn thành, hàm successFunc hoặc hàm failFunc của mới có thể chạy. Nếu Promise được thực hiện, hàm sucessFunc được gọi. Nếu Promise thất bại, hàm failureFunc được gọi.

5. Ví dụ về Promise

Bây giờ chúng ta hãy thử tạo mới một Promise xem nhé:

function delay(t){
  return new Promise(function(resolve){
    return setTimeout(resolve, t)
  });
}
function logHi(){
  console.log('hi');
}
delay(2000).then(logHi);

Ở ví dụ trên chúng ta có hai function - delay()logHi(). Hàm logHi() in ra 'hi' trên giao diện console ở trình duyệt. Hàm delay() phức tạp hơn một chút. Nó trả về một Promiseđể thực hiện một khung thời gian t được cung cấp.

Chúng ta sử dụng phương thức then() để đăng ký callback để Promise nhận được giá trị fulfilled hoặc rejected.

Chúng ta có thể sử dụng delay(2000).then(logHi)để đặt thời gian trong 2000 mili giây (2 giây) vào cho việc delay của ví dụ trên. Sau 2 giây đã trôi qua, Promise sẽ được thực hiện, và chỉ khi đó hàm logHi mới được gọi.

6. Chaining Promises

Một trong những lợi ích chính của Promises là chúng cho phép chúng ta kết nối các hoạt động không đồng bộ với nhau. Điều này có nghĩa là chúng ta có thể chỉ định các hoạt động tiếp theo để bắt đầu chỉ khi hoạt động trước đó đã thành công. Đây được gọi là Chaining Promises. Dưới đây là một ví dụ:

new Promise(function(resolve, reject) {
  setTimeout(() => resolve(1), 2000);
  
}).then((result) => {
  alert(result);
  return result + 2;
  
}).then((result) => {
  alert(result);
  return result + 2;
  
}).then((result) => {
  alert(result);
  return result + 2;
});

(Bạn có thể paste vào console của trình duyệt để test thử.)

Ở trên, Promise ban đầu sẽ giải quyết trong 2000 mili giây với giá trị là 1. Sau khi giải quyết, trình xử lý then() được gọi và giá trị 1 được in lên màn hình console. Cuối cùng, giá trị được thêm vào 2 và giá trị 3 được trả về. Giá trị này được chuyển cho trình xử lý tiếp theo sau đó () và quá trình lặp lại.

Rõ ràng đây không phải là một ví dụ trong các dự án thực, nhưng nó sẽ minh họa cho bạn cách mà Promise có thể được kết nối với nhau. Điều này rất hữu ích với một số tác vụ nhất định trong JavaScript như tải tài nguyên bên ngoài hoặc chờ dữ liệu API trước khi xử lý.

7. Error Handling

Cho đến thời điểm này, chúng ta mới chỉ thao tác với các Promise có thể xử lý. Ngoài ra, chúng ta có thể sử dụng .catch () để bắt tất cả các lỗi trong Promise chaining .

Hãy thử xem xét một ví dụ nhé:

// ....
})
.catch((e) => {
  console.log('error: ', e)
}

Ví dụ trên là một cách sử dụng .catch() đơn giản để nhận được thông báo lỗi và trả về trên màn hình console.

Bây giờ chúng ta hãy thêm phần xử lý lỗi .catch() vào ví dụ trên:

new Promise(function(resolve, reject) {
  setTimeout(() => resolve(1), 2000);

}).then((result) => {
  alert(result);
  return result + 2;
  
}).then((result) => {
  throw new Error('FAILED HERE');
  alert(result);
  return result + 2;
  
}).then((result) => {
  alert(result);
  return result + 2;
  
}).catch((e) => {
  console.log('error: ', e)
});

Ví dụ trên chỉ có 2 sự thay đổi, đó là sau .then() thứ hai, chúng ta đã thêm một lỗi Error('FAILED HERE'); và phần bắt lỗi .catch() ở cuối chuỗi.

Những gì đã xảy ra là:

Promise chạy sau 2 giây với giá trị là 1. Giá trị này pass .then() đầu tiên và được alert trên màn hình. Tiếp theo nó gặp .then() thứ 2 và một lỗi được tạo mới. Việc thực thi được dừng lại ngay lập tức và Promise chuyển đến trạng thái rejected. .catch() nhận giá trị lỗi và in vào console của trình duyệt.

Kết quả sẽ như hình:

8. Kết luận

Hi vọng bài viết giúp bạn có cái nhìn khách quan về Promise trong javascript

Cảm ơn đã theo dõi (bow)

Tài liệu tham khảo: https://codeburst.io/javascript-learn-promises-f1eaa00c5461


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í