Bạn đã dùng Promise.allSettled() đúng cách chưa?

Promise.all là một phương thức không thể thiếu và được sử dụng rộng rãi trong lập trình đồng bộ đối với lập trình viên. Nhưng còn Promise.allSettled thì sao? Hãy cũng ICTS tìm hiểu thêm về khái niệm này và cách dùng nó nhé!

Promise.allSettled là một hàm trợ giúp thực thi các  promises song song và tích hợp các trạng thái đã giải quyết (fulfilled hoặc rejected) thành một mảng kết quả và trạng thái  của các promise . 

Cùng xem Promise.allSettled() được sử dụng như thế nào nhé

1. Promise.allSettled() là gì?

Promise.allSettled() sẽ hữu ích khi thực hiện song song các hoạt động bất đồng bộ một cách độc lập và thu thập kết quả của chúng.

Function này nhận vào một mảng (hoặc một iterable) các promises như một tham số

const statusesPromise = Promise.allSettled(promises);

Khi tất cả các promises truyền vào được báo fulfilled hoặc rejected, statusesPromise sẽ trả về một mảng có các trạng thái của chúng, gồm:

{ status: 'fulfilled', value: value } — Nếu promise tương ứng thành công (fulfilled)
{ status: 'rejected', reason: reason } — Nếu promise tương ứng thất bại (rejected)

undefined

Sau khi tất cả promises đã được resolve, ta có thể trích xuất các trạng thái bằng cách sử dụng cú pháp then:

statusesPromise.then(statuses => {
 statuses; // [{ status: '...', value: '...' }, ...]
});

Hoăc sử dụng cú pháp async/await:

const statuses = await statusesPromise;

statuses; // [{ status: '...', value: '...' }, ...]

Các Promises được trả về từ Promise.allSettled() luôn luôn fulfill với 1 mảng các trạng thái, bất kể một hoặc tất cả các promise đều bị reject.

2. Bài toán về hoa quả và rau củ

Trước khi đi sâu vào Promise.allSettle(), hãy định nghĩa 2 helper function đơn giản này nhé.

Đầu tiên, resolveTimeout(value, delay) — trả lại một promise được fulfill với  value sau một khoảng thời gian delay:

function resolveTimeout(value, delay) {
  return new Promise(
    resolve => setTimeout(() => resolve(value), delay)
  );
}

Function thứ 2,  rejectTimeout(reason, delay) — trả lại một promise bị reject với  reason sau một khoảng thời gian delay:

function rejectTimeout(reason, delay) {
  return new Promise(
    (r, reject) => setTimeout(() => reject(reason), delay)
  );
}

Hãy thử phân tích các trường hợp sau nha:

2.1  Tất cả promises đều fulfill

Bài toán đặt ra là, cần lấy cùng lúc các loại rau củ và trái cây có sẵn cửa hàng hàng tạp hóa. Đây là một công việc bất đồng bộ:

const statusesPromise = Promise.allSettled([
  resolveTimeout(['potatoes', 'tomatoes'], 1000),
  resolveTimeout(['oranges', 'apples'], 1000)
]);

// wait...
const statuses = await statusesPromise;

// after 1 second
console.log(statuses); 
// [
//   { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
//   { status: 'fulfilled', value: ['oranges', 'apples'] }
// ]

Xem Demo tại đây

Promise.allSettled([…]) trả về statusesPromise là một mảng các promise sẽ được resolve sau 1 giây, ngay sau khi rau củ và hoa quả được resolve đồng thời

statusesPromise là một mảng có chứa các trạng thái:

Item đầu tiên của mảng  có status là fulfilled và value là mảng các loại rau củ: { status: ‘fulfilled’, value: [‘potatoes’, ‘tomatoes’] }
Tương tự, item thứ 2 của mảng có status là fulfilled và value là mảng các loại trái cây: { status: ‘fulfilled’, value: [‘oranges’, ‘apples’] }

2.2 Có một promise bị reject

Hãy tưởng tượng, trong cửa hàng không còn trái cây, trong trường hợp này, chúng ta sẽ reject promise với value là trái cây. Vậy lúc này Promise.allSettled() sẽ hoạt động như thế nào?

const statusesPromise = Promise.allSettled([
  resolveTimeout(['potatoes', 'tomatoes'], 1000),
  rejectTimeout(new Error('Out of fruits!'), 1000)
]);

// wait...
const statuses = await statusesPromise;

// after 1 second
console.log(statuses); 
// [
//   { status: 'fulfilled', value: ['potatoes', 'tomatoes'] },
//   { status: 'rejected', reason: Error('Out of fruits!') }
// ]

Xem Demo tại đây 

Promise được trả về bởi Promise.allSettled([…]) resolve sau 1 giây sẽ là một array có status như sau:

Item đầu tiên của array có status là fulfilled và value là mảng các loại rau củ là:  { status: ‘fulfilled’, value: [‘potatoes’, ‘tomatoes’] }
Ở Item thứ 2, do promise có value hoa quả lỗi và bị reject, nên hiển thị status là: { status: ‘rejected’, reason: Error(‘Out of fruits’) }.
Mặc dù promise thứ 2 bị reject, statusesPromise vẫn giải quyết thành công với một mảng các status.

2.3 Tất cả các promise đều bị reject

Vậy khi cửa hàng hết sạch cả rau củ và hoa quả thì sao? Trong trường hợp này, tất cả các promise sẽ bị reject:

<code class="language-javascript">const statusesPromise = Promise.allSettled([
  rejectTimeout(new Error('Out of vegetables!'), 1000),  rejectTimeout(new Error('Out of fruits!'), 1000)]);

// wait...
const statuses = await statusesPromise;

// after 1 second
console.log(statuses); 
// [
//   { status: 'rejected', reason: Error('Out of vegetables!')  },
//   { status: 'rejected', reason: Error('Out of fruits!') }
// ]

Xem Demo tại đây

Trong trường hợp này, statusPromise vẫn giải quyết thành công và trả về một mảng các status. Tuy nhiên, mảng này chỉ chứa các status rejected

3. Kết luận

Promise.allSettled(promises) cho phép bạn thực thi các promise song song và thu thập các status khác nhau (fulfilled hoặc rejected) và đưa vào một mảng.

Promise.allSettled() sẽ hữu ích khi thực hiện song song các hoạt động bất đồng bộ một cách độc lập và thu thập kết quả của chúng.

Challenge: Bạn có thấy sự khác nhau giữa Promise.all và Promise.allSettled() không ? Comment đáp án ngay bên dưới nhé!!!

Link bài viết gốc: https://dmitripavlutin.com/promise-all-settled/


Son Chu

You Might Also Like


0 Comment


    Would you like to share your thoughts?

    Your email address will not be published. Required fields are marked *

    This field is required.
    Please provide a valid email address.
    This field is required.