成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Promise.allSettled 的作用,如何自己實現一個 Promise.allSettled

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

[[396102]]

本文轉載自微信公眾號「三分鐘學前端」,作者sisterAn。轉載本文請聯系三分鐘學前端公眾號。

引言

本文從四個方面循序漸進介紹 Promise.allSettled :

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

下面正文開始??

Promise.all() 的缺陷

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

  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 ,數組中其它未執行完的 promise 依然是在執行的, Promise.all 沒有采取任何措施來取消它們的執行

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

Promise.allSettled()

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

  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. */ 

當瀏覽器不支持 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 的執行結果

Promise.all() 更適合:

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

手寫 Promise.allSettled 源碼

與 Promise.all 不同的是,當 promise 被 reject 之后,我們不會直接 reject ,而是記錄下該 reject 的值和對應的狀態 'rejected' ;

同樣地,當 promise 對象被 resolve 時我們也不僅僅局限于記錄值,同時也會記錄狀態 'fulfilled' 。

當所有的 promise 對象都已執行(解決或拒絕),我們統一 resolve 所有的 promise 執行結果數組

  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.       // 如果傳入的是一個空數組,那么就直接返回一個resolved的空數組promise對象 
  7.       if (len === 0) return resolve([]) 
  8.       // 將傳入的參數轉化為數組,賦給args變量 
  9.       let args = Array.prototype.slice.call(promises) 
  10.       // 計算當前是否所有的 promise 執行完成,執行完畢則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.   } 

總結

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

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

 

責任編輯:武曉燕 來源: 三分鐘學前端
相關推薦

2024-08-27 09:16:15

接口代碼狀態

2023-10-04 07:25:59

JavaScriptpromises

2025-05-08 08:35:00

異步編程JavaScriptAPI

2025-01-22 08:29:36

AsyncJavaScript異步

2021-04-28 08:21:21

Promise.any服務器場景

2025-04-23 09:47:57

開發場景請求

2023-07-11 09:07:49

數組Promise方法

2021-04-29 08:28:24

架構參數傳遞

2020-09-24 11:46:03

Promise

2025-06-13 09:40:45

2024-05-20 01:10:00

Promise變量

2018-03-13 16:04:45

Promise執行順序

2018-07-03 15:20:36

Promise函數借錢

2020-12-15 08:01:24

Promise參數ES6

2023-09-15 15:31:23

異步編程Promise

2017-05-11 20:20:59

JavascriptPromiseWeb

2020-07-29 17:35:08

Promise源碼前端

2021-09-02 12:07:48

Swift 監聽系統Promise

2021-03-09 07:37:42

技術Promise測試

2022-09-28 12:23:36

Promise代碼
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 亚洲精品久久久一区二区三区 | 91电影| aaaa网站 | 国产美女精品视频免费观看 | 国产成人a亚洲精品 | 欧美激情a∨在线视频播放 成人免费共享视频 | av在线电影网站 | 草久久| 国产精品久久久久久妇女 | 国产婷婷精品 | 国产综合久久久久久鬼色 | 午夜在线 | 午夜影院网站 | 成人免费大片黄在线播放 | 日韩字幕| 免费视频成人国产精品网站 | 午夜视频导航 | 国产午夜精品久久久 | 最新中文在线视频 | 欧美一区二区三区久久精品视 | 日韩av在线中文字幕 | 日日想夜夜操 | 国产精品欧美一区二区三区不卡 | 久久大 | 99精品99 | 第一福利社区1024 | 91久操视频 | xxxxxx国产 | 一区二区三区精品在线 | 天天插天天操 | 毛片免费看的 | 久久综合狠狠综合久久综合88 | 日日操夜夜操天天操 | 亚洲欧美中文日韩在线v日本 | com.国产 | 国产午夜精品一区二区三区嫩草 | 国产日韩久久久久69影院 | 免费在线视频a | 日本一区二区三区精品视频 | 看a级黄色毛片 | 免费看的黄网站 |