一文搞懂 Promise 新 Api allSettled 的用法和 all 區別,以及如何在不支援新特性的環境下實現一個 Polyfill

騷豬佩琦發表於2023-04-28

開始

一文搞懂 Promise 新 Api allSettled 的用法和 all 區別,以及如何在不支援新特性的環境下實現一個 Polyfill

allSettled 的用法

const runAllSettled = async () => {
    const successPromise = Promise.resolve('success') // 一個正常返回的 Promise
    const failPromise = Promise.reject('fail') // 一個異常返回的 Promise
    // 使用 allSettled
    const settiled = await Promise.allSettled([successPromise, failPromise, undefined, null])
    console.log(settiled)
    /*  輸出結果如下
            [
                {status: 'fulfilled', value: 'success'},
                {status: 'rejected', reason: 'fail'},
                {status: 'fulfilled', value: undefined},
                {status: 'fulfilled', value: null},
            ]
    */
}
runAllSettled()
  • 返回一個陣列,每一個元素都是一個物件,裡面必然包含 status 屬性
  • status 屬性只會有兩個值,fulfilled 或者 rejected,非黑即白的既視感
  • allSettled 總是走 then 的,也就是併發的 Promise 出現 reject 也不會走 catch,需要自行遍歷返回的陣列,判斷 status 來做錯誤捕獲
  • 物件中還有另外兩個屬性,valuereason。根據 promise 的狀態返回,如果成功返回,即為 value,反之為 reason
  • 更詳細的 TS 型別在這裡 lib.es2020.promise.d.ts

all 的用法

  • all 的用法就不再詳細贅述,可前往 MDN 檢視

區別

功 能 Promise.all Promise.allSettled
併發
併發Promise中出現 reject 是否還走 then

在不支援 Promise.allSettled 新特性的環境下實現一個 Polyfill

// 透過 Promise.all 實現 Promise.allSettled
if (!Promise.allSettled) {
	Promise.allSettled = function (promises) {
		return Promise.all(
			promises.map((p) =>
				Promise.resolve(p).then(
					(value) => ({
						status: "fulfilled",
						value,
					}),
					(reason) => ({
						status: "rejected",
						reason,
					})
				)
			)
		);
	};
}

相關文章