自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Promise.allSettled 的作用,如何自己實(shí)現(xiàn)一個 Promise.allSettled

開發(fā) 前端
只要其中任何一個promise 失敗都會執(zhí)行 reject ,并且 reject 的是第一個拋出的錯誤信息,只有所有的 promise 都 resolve 時才會調(diào)用 .then 中的成功回調(diào)。

[[396102]]

本文轉(zhuǎn)載自微信公眾號「三分鐘學(xué)前端」,作者sisterAn。轉(zhuǎn)載本文請聯(lián)系三分鐘學(xué)前端公眾號。

引言

本文從四個方面循序漸進(jìn)介紹 Promise.allSettled :

  • Promise.all() 的缺陷
  • 引入 Promise.allSettled()
  • Promise.allSettled() 與 Promise.all() 各自的適用場景
  • 手寫 Promise.allSettled() 實(shí)現(xiàn)

下面正文開始??

Promise.all() 的缺陷

我們在之前的一篇文章中 面試官問:Promise.all 使用、原理實(shí)現(xiàn)及錯誤處理 已經(jīng)介紹過,當(dāng)我們使用 Promise.all() 執(zhí)行過個 promise 時,只要其中任何一個promise 失敗都會執(zhí)行 reject ,并且 reject 的是第一個拋出的錯誤信息,只有所有的 promise 都 resolve 時才會調(diào)用 .then 中的成功回調(diào)

  1. const p1 = Promise.resolve(1) 
  2. const p2 = Promise.resolve(2) 
  3. const p3 = new Promise((resolve, reject) => { 
  4.   setTimeout(reject, 1000, 'three'); 
  5. }); 
  6.  
  7. Promise.all([p1, p2, p3]) 
  8. .then(values => { 
  9.     console.log('resolve: 'values
  10. }).catch(err => { 
  11.     console.log('reject: ', err) 
  12. })  
  13.  
  14. // reject:  three 

注意:其中任意一個 promise 被 reject ,Promise.all 就會立即被 reject ,數(shù)組中其它未執(zhí)行完的 promise 依然是在執(zhí)行的, Promise.all 沒有采取任何措施來取消它們的執(zhí)行

但大多數(shù)場景中,我們期望傳入的這組 promise 無論執(zhí)行失敗或成功,都能獲取每個 promise 的執(zhí)行結(jié)果,為此,ES2020 引入了 Promise.allSettled()

Promise.allSettled()

Promise.allSettled() 可以獲取數(shù)組中每個 promise 的結(jié)果,無論成功或失敗

  1. const p1 = Promise.resolve(1) 
  2. const p2 = Promise.resolve(2) 
  3. const p3 = new Promise((resolve, reject) => { 
  4.   setTimeout(reject, 1000, 'three'); 
  5. }); 
  6.  
  7. Promise.allSettled([p1, p2, p3]) 
  8. .then(values => { 
  9.     console.log(values
  10. })  
  11.  
  12. /* 
  13.   {status: "fulfilled", value: 1},  
  14.   {status: "fulfilled", value: 2},  
  15.   {status: "rejected", reason: "three"
  16. */ 

當(dāng)瀏覽器不支持 Promise.allSettled ,可以如此 polyfill:

  1. if (!Promise.allSettled) { 
  2.   const rejectHandler = reason => ({status: "rejected", reason}) 
  3.   const resolveHandler = value => ({status: "fulfilled", value}) 
  4.   Promise.allSettled = promises => 
  5.     Promise.all
  6.       promises.map((promise) => 
  7.         Promise.resolve(promise)  
  8.           .then(resolveHandler, rejectHandler) 
  9.       ) 
  10.       // 每個 promise 需要用 Promise.resolve 包裹下 
  11.       // 以防傳遞非 promise 
  12.     ); 
  13.  
  14. // 使用 
  15. const p1 = Promise.resolve(1) 
  16. const p2 = Promise.resolve(2) 
  17. const p3 = new Promise((resolve, reject) => { 
  18.   setTimeout(reject, 1000, 'three'); 
  19. }) 
  20. const promises = [p1, p2, p3] 
  21. Promise.allSettled(promises).then(console.log) 

Promise.allSettled() 與 Promise.all() 各自的適用場景

Promise.allSettled() 更適合:

  • 彼此不依賴,其中任何一個被 reject ,對其它都沒有影響
  • 期望知道每個 promise 的執(zhí)行結(jié)果

Promise.all() 更適合:

  • 彼此相互依賴,其中任何一個被 reject ,其它都失去了實(shí)際價值

手寫 Promise.allSettled 源碼

與 Promise.all 不同的是,當(dāng) promise 被 reject 之后,我們不會直接 reject ,而是記錄下該 reject 的值和對應(yīng)的狀態(tài) 'rejected' ;

同樣地,當(dāng) promise 對象被 resolve 時我們也不僅僅局限于記錄值,同時也會記錄狀態(tài) 'fulfilled' 。

當(dāng)所有的 promise 對象都已執(zhí)行(解決或拒絕),我們統(tǒng)一 resolve 所有的 promise 執(zhí)行結(jié)果數(shù)組

  1. MyPromise.allSettled = function (promises) { 
  2.     return new MyPromise((resolve, reject) => { 
  3.       promises = Array.isArray(promises) ? promises : [] 
  4.       let len = promises.length 
  5.       const argslen = len 
  6.       // 如果傳入的是一個空數(shù)組,那么就直接返回一個resolved的空數(shù)組promise對象 
  7.       if (len === 0) return resolve([]) 
  8.       // 將傳入的參數(shù)轉(zhuǎn)化為數(shù)組,賦給args變量 
  9.       let args = Array.prototype.slice.call(promises) 
  10.       // 計算當(dāng)前是否所有的 promise 執(zhí)行完成,執(zhí)行完畢則resolve 
  11.       const compute = () => { 
  12.         if(--len === 0) {  
  13.           resolve(args) 
  14.         } 
  15.       } 
  16.       function resolvePromise(index, value) { 
  17.         // 判斷傳入的是否是 promise 類型 
  18.         if(value instanceof MyPromise) {  
  19.           const then = value.then 
  20.           then.call(value, function(val) { 
  21.             args[index] = { status: 'fulfilled', value: val} 
  22.             compute() 
  23.           }, function(e) { 
  24.             args[index] = { status: 'rejected', reason: e } 
  25.             compute() 
  26.           }) 
  27.         } else { 
  28.           args[index] = { status: 'fulfilled', value: value} 
  29.           compute() 
  30.         } 
  31.       } 
  32.     
  33.       for(let i = 0; i < argslen; i++){ 
  34.         resolvePromise(i, args[i]) 
  35.       } 
  36.     }) 
  37.   } 

總結(jié)

彼此相互依賴,一個失敗全部失效(全無或全有)用 Promise.all ;相互獨(dú)立,獲取每個結(jié)果用 Promise.allSettled

來自:https://github.com/sisterAn/blog

 

責(zé)任編輯:武曉燕 來源: 三分鐘學(xué)前端
相關(guān)推薦

2024-08-27 09:16:15

接口代碼狀態(tài)

2023-10-04 07:25:59

JavaScriptpromises

2025-01-22 08:29:36

AsyncJavaScript異步

2021-04-28 08:21:21

Promise.any服務(wù)器場景

2025-04-23 09:47:57

開發(fā)場景請求

2023-07-11 09:07:49

數(shù)組Promise方法

2021-04-29 08:28:24

架構(gòu)參數(shù)傳遞

2020-09-24 11:46:03

Promise

2024-05-20 01:10:00

Promise變量

2018-03-13 16:04:45

Promise執(zhí)行順序

2018-07-03 15:20:36

Promise函數(shù)借錢

2023-09-15 15:31:23

異步編程Promise

2020-12-15 08:01:24

Promise參數(shù)ES6

2017-05-11 20:20:59

JavascriptPromiseWeb

2020-07-29 17:35:08

Promise源碼前端

2021-09-02 12:07:48

Swift 監(jiān)聽系統(tǒng)Promise

2021-03-09 07:37:42

技術(shù)Promise測試

2022-09-28 12:23:36

Promise代碼

2017-04-10 15:57:10

AsyncAwaitPromise

2022-09-15 07:54:59

awaitPromise
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號