2024年3月28日 星期四

[Javascript] 四種併發 Promise 差異比較


Promise 代表非同步操作的物件,一個 Promise 可區分成三種狀態:

  • pending - 初始狀態,可以視為處理中
  • fulfilled - 表示操作成功
  • rejected - 表示操作失敗

Promise 的併發控制就是當我們傳入多個 Promise時,藉由達成不同的條件,返回不同狀態的 Promise。


Promise.all()

當輸入的所有 Promise 的狀態都為 fulfilled 時,回傳 Promise 也是 fulfilled、操作成功;可按照輸入 Promise 的順序取得其回傳值。若有任何一項 rejected,立即判定操作失敗。

Promise.all([requestA, requestB, requestC]).then(result => {
    const [resultA, resultB, resultC] = result;
    
    // 全部都成功
}).catch(err => {
    // 可取得第一個失敗原因 
    console.log(err);
})
全部成功才是成功

Promise.allSettled()

當輸入的所有 Promise 的執行完畢時,不論為 fulfilled、rejected,回傳 Promise 必為 fulfilled;可按照其輸入的順序,取得各別的狀態(status)、回傳值(value)或錯誤原因(reason)。

Promise.all([requestA, requestB, requestC]).then(result => {
    const [resultA, resultB, resultC] = result;
    
    // 操作成功時,可以取得回傳值
    // result = {status: 'fulfilled', value: 'Great Job!'}
    // 操作失敗時,可以取得原因
    // result = {status: 'rejected', reason: 'Because ....'}
})
全部完成比較重要,但誰輸誰贏很清楚

Promise.any()

當輸入的所有 Promise 有任一個操作成功時,回傳 Promise 狀態為 fulfilled,且可取得其回傳值。若沒有任何一項成功,則是 rejected,錯誤原因是AggregateError。

Promise.any([requestA, requestB, requestC]).then(result => {
  // 取得最快成功的回傳值
  console.log(result);
}).catch(err => {
  // AggregateError: No Promise in Promise.any was resolved
  console.log(err);
});
龜兔賽跑,爭取第一名

Promise.race()

當輸入的所有 Promise 有任一個操作完成時,根據其狀態決定回傳 Promise 狀態,若第一個操作結果為成功,則為回傳狀態為 fulfilled;反之是 rejected。

Promise.race([requestA, requestB, requestC]).then(result => {
  // 第一個人成功,走這條路
  console.log(result);
}).catch(err => {
  // 第一個人失敗,走這條路
  console.log(err);
});
成敗不是關鍵,速度才是絕對