<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          字節(jié)飛書(shū)面試——請(qǐng)實(shí)現(xiàn) Promise.all

          共 13055字,需瀏覽 27分鐘

           ·

          2022-04-26 01:02

          前言

          金三銀四,身為大四即將成為畢業(yè)生的我迫不及待地將簡(jiǎn)歷投進(jìn)了字節(jié)的飛書(shū)部門(mén),本想著掂量一下幾斤幾兩,沒(méi)想到這一掂就露餡了??,去大廠(chǎng)的夢(mèng)想就這么跌倒在了Promsie.all上。但年輕人總是要有斗志的,從哪里跌到就從哪里爬起來(lái)!下面是復(fù)盤(pán)時(shí)間。

          何為Promise.all?

          Promise.all 是 es6 Promise 對(duì)象上的一個(gè)方法,它的功能就是將多個(gè)Promise實(shí)例包裝成一個(gè)promise實(shí)例。以下是 MDN 對(duì) Promise.all 的描述:

          Promise.all() 方法接收一個(gè) promise 的 iterable 類(lèi)型(注:Array,Map,Set都屬于ES6的iterable類(lèi)型)的輸入,并且只返回一個(gè)`Promise`[1]實(shí)例,?那個(gè)輸入的所有 promise 的 resolve 回調(diào)的結(jié)果是一個(gè)數(shù)組。這個(gè)`Promise`[2]的 resolve 回調(diào)執(zhí)行是在所有輸入的 promise 的 resolve 回調(diào)都結(jié)束,或者輸入的 iterable 里沒(méi)有 promise 了的時(shí)候。它的 reject 回調(diào)執(zhí)行是,只要任何一個(gè)輸入的 promise 的 reject 回調(diào)執(zhí)行或者輸入不合法的 promise 就會(huì)立即拋出錯(cuò)誤,并且reject的是第一個(gè)拋出的錯(cuò)誤信息。

          我戴上我的300度近視眼鏡,仔細(xì)地提取出這段描述中的關(guān)鍵字

          1. Promise.all 的返回值是一個(gè)新的 Promise 實(shí)例。
          2. Promise.all 接受一個(gè)可遍歷的數(shù)據(jù)容器,容器中每個(gè)元素都應(yīng)是 Promise 實(shí)例。咱就是說(shuō),假設(shè)這個(gè)容器就是數(shù)組。
          3. 數(shù)組中每個(gè) Promise 實(shí)例都成功時(shí)(由pendding狀態(tài)轉(zhuǎn)化為fulfilled狀態(tài)),Promise.all 才成功。這些 Promise 實(shí)例所有的 resolve 結(jié)果回按原來(lái)的順序集合在一個(gè)數(shù)組中作為 Promise.allresolve 的結(jié)果。
          4. 數(shù)組中只要有一個(gè) Promise 實(shí)例失敗(由pendding狀態(tài)轉(zhuǎn)化為rejected狀態(tài)),Promise.all 就失敗。Promise.all.catch() 會(huì)捕獲到這個(gè) reject

          原生 Promise.all 測(cè)試

          咱先看看原生的Promise.all的是啥效果。

          const?p1?=?Promise.resolve('p1')

          const?p2?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p2?延時(shí)一秒')
          ??},?1000)
          })

          const?p3?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p3?延時(shí)兩秒')
          ??},?2000)
          })

          const?p4?=?Promise.reject('p4?rejected')

          const?p5?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????reject('p5?rejected?延時(shí)1.5秒')
          ??},?1500)
          })

          //?所有Promise實(shí)例都成功
          Promise.all([p1,?p2,?p3])
          ??.then(res?=>?{
          ????console.log(res)
          ??})
          ??.catch(err?=>?console.log(err))?//?2秒后打印?[?'p1',?'p2?延時(shí)一秒',?'p3?延時(shí)兩秒'?]
          ??
          //?一個(gè)Promise實(shí)例失敗
          Promise.all([p1,?p2,?p4])
          ??.then(res?=>?{
          ????console.log(res)
          ??})
          ??.catch(err?=>?console.log(err))?//?p4?rejected
          ??
          //?一個(gè)延時(shí)失敗的Promise
          ?Promise.all([p1,?p2,?p5])
          ??.then(res?=>?{
          ????console.log(res)
          ??})
          ??.catch(err?=>?console.log(err))?//?1.5秒后打印?p5?rejected
          ??
          //?兩個(gè)Promise實(shí)例失敗
          Promise.all([p1,?p4,?p5])
          ??.then(res?=>?{
          ????console.log(res)
          ??})
          ??.catch(err?=>?console.log(err))?//?p4?rejected


          復(fù)制代碼

          注意

          上面 p4p5 在未傳入 Promise.all 時(shí)需要注釋掉,因?yàn)橐粋€(gè)調(diào)用了 rejectPromise 實(shí)例如果沒(méi)有使用 .catch() 方法去捕獲錯(cuò)誤會(huì)報(bào)錯(cuò)。但如果 Promise 實(shí)例定義了自己的 .catch,就不會(huì)觸發(fā) Promise.all.catch() 方法。

          OK,理論存在,實(shí)踐開(kāi)始!

          手動(dòng)實(shí)現(xiàn)Promise.all

          1. `Promise.all` 接受一個(gè)數(shù)組,返回值是一個(gè)新的 `Promise` 實(shí)例
          Promise.MyAll?=?function?(promises)?{
          ??return?new?Promise((resolve,?reject)?=>?{

          ??})
          }
          復(fù)制代碼
          1. 數(shù)組中所有 `Promise` 實(shí)例都成功,`Promise.all` 才成功。不難想到,咱得需要一個(gè)數(shù)組來(lái)收集這些 `Promise` 實(shí)例的 `resolve` 結(jié)果。但有句俗話(huà)說(shuō)得好:“不怕一萬(wàn),就怕萬(wàn)一”,萬(wàn)一數(shù)組里面有元素不是 `Promise`咋辦 —— 那就得用 `Promise.resolve()` 把它辦了。這里還有一個(gè)問(wèn)題,`Promise` 實(shí)例是不能直接調(diào)用 `resolve` 方法的,咱得在 `.then()` 中去收集結(jié)果。注意要保持結(jié)果的順序。
          Promise.MyAll?=?function?(promises)?{
          ??let?arr?=?[]
          ??return?new?Promise((resolve,?reject)?=>?{
          ????promises.forEach((item,?i)?=>?{
          ??????Promise.resolve(item).then(res?=>?{
          ????????arr[i]?=?res
          ??????})
          ????})?
          ??})
          }
          復(fù)制代碼
          1. 將收集到的結(jié)果(數(shù)組`arr`)作為參數(shù)傳給外層的 `resolve` 方法。這里咱們肯定是有一個(gè)判斷條件的,如何判斷所有 `Promise` 實(shí)例都成功了呢?新手容易寫(xiě)出這句代碼(沒(méi)錯(cuò)就是我本人了??):
          if?(arr.length?===?promises.length)?resolve(arr)
          復(fù)制代碼

          咱仔細(xì)想想 Promise 使用來(lái)干嘛的 —— 處理異步任務(wù)。對(duì)呀,異步任務(wù)很多都需要花時(shí)間呀,如果這些 Promise 中最后一個(gè)先完成呢?那 arr 數(shù)組不就只有最后一項(xiàng)了,前面的所有項(xiàng)都是 empty。所以這里咱們應(yīng)該創(chuàng)建一個(gè)計(jì)數(shù)器,每有一個(gè) Promise 實(shí)例成功,計(jì)數(shù)器加一:

          Promise.MyAll?=?function?(promises)?{
          ??let?arr?=?[],
          ????count?=?0
          ??return?new?Promise((resolve,?reject)?=>?{
          ????promises.forEach((item,?i)?=>?{
          ??????Promise.resolve(item).then(res?=>?{
          ????????arr[i]?=?res
          ????????count?+=?1
          ????????if?(count?===?promises.length)?resolve(arr)
          ??????})
          ????})
          ??})
          }
          復(fù)制代碼
          1. 最后就是處理失敗的情況了,這里有兩種寫(xiě)法,第一種是用 `.catch()` 方法捕獲失?。?br>
          Promise.MyAll?=?function?(promises)?{
          ??let?arr?=?[],
          ????count?=?0
          ??return?new?Promise((resolve,?reject)?=>?{
          ????promises.forEach((item,?i)?=>?{
          ??????Promise.resolve(item).then(res?=>?{
          ????????arr[i]?=?res
          ????????count?+=?1
          ????????if?(count?===?promises.length)?resolve(arr)
          ??????}).catch(reject)
          ????})
          ??})
          }
          復(fù)制代碼

          第二種寫(xiě)法就是給 .then() 方法傳入第二個(gè)參數(shù),這個(gè)函數(shù)是處理錯(cuò)誤的回調(diào)函數(shù):

          Promise.MyAll?=?function?(promises)?{
          ??let?arr?=?[],
          ????count?=?0
          ??return?new?Promise((resolve,?reject)?=>?{
          ????promises.forEach((item,?i)?=>?{
          ??????Promise.resolve(item).then(res?=>?{
          ????????arr[i]?=?res
          ????????count?+=?1
          ????????if?(count?===?promises.length)?resolve(arr)
          ??????},?reject)
          ????})
          ??})
          }
          復(fù)制代碼

          測(cè)試案例

          致此 Promise.all 大功告成,趕緊拿來(lái)測(cè)試一下(摩拳擦掌):

          const?p1?=?Promise.resolve('p1')
          const?p2?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p2?延時(shí)一秒')
          ??},?1000)
          })
          const?p3?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p3?延時(shí)兩秒')
          ??},?2000)
          })

          const?p4?=?Promise.reject('p4?rejected')

          const?p5?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????reject('p5?rejected?延時(shí)1.5秒')
          ??},?1500)
          })

          //?所有?Promsie?都成功
          Promise.MyAll([p1,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?2秒后打印?[?'p1',?'p2?延時(shí)一秒',?'p3?延時(shí)兩秒'?]
          ??
          //?一個(gè)?Promise?失敗
          Promise.MyAll([p1,?p2,?p4])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p4?rejected
          ??
          //?一個(gè)延時(shí)失敗的?Promise
          Promise.MyAll([p1,?p2,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?1.5秒后打印?p5?rejected?延時(shí)1.5秒
          ?
          //?兩個(gè)失敗的?Promise
          Promise.MyAll([p1,?p4,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p4?rejected
          復(fù)制代碼

          “OhOhOhOh~~~~”,與原生的 Promise.all運(yùn)行結(jié)果不能說(shuō)很像,只能說(shuō)一模一樣。老話(huà)說(shuō)的好,趁熱打鐵——正在火候上。我打開(kāi)某個(gè)學(xué)習(xí)網(wǎng)站(MDN Web Docs \(mozilla.org\)[3]),了解到 Promise 對(duì)象用于同時(shí)處理多個(gè) Promise 的方法還有 Promise.racePromise.any、Promise.allSettle。從小老師就教會(huì)了咱們舉一反三,仔細(xì)看了這三個(gè)方法的描述之后,我還真給反出來(lái)了??。

          Promise.race

          Promise.race 從字面意思理解就是賽跑,以狀態(tài)變化最快的那個(gè) Promise 實(shí)例為準(zhǔn),最快的 Promise 成功 Promise.race 就成功,最快的 Promise 失敗 Promise.race 就失敗。

          咱來(lái)看看原生 Promise.race 效果

          原生 Promise.race 測(cè)試

          const?p1?=?Promise.resolve('p1')
          const?p2?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p2?延時(shí)一秒')
          ??},?1000)
          })
          const?p3?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p3?延時(shí)兩秒')
          ??},?2000)
          })

          const?p4?=?Promise.reject('p4?rejected')

          const?p5?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????reject('p5?rejected?延時(shí)1秒')
          ??},?1500)
          })

          //?p1無(wú)延時(shí),p2延時(shí)1s,p3延時(shí)2s
          Promise.race([p1,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p1

          //?p4無(wú)延時(shí)reject
          Promise.race([p4,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p4?rejected
          ??
          //?p5?延時(shí)1.5秒reject,p2延時(shí)1s
          Promise.race([p5,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?1s后打印:?p2?延時(shí)一秒
          復(fù)制代碼

          理論存在,實(shí)踐開(kāi)始

          手寫(xiě)Promise.race

          整體流程與 Promise 差不多,只是對(duì)數(shù)組中的 Promise 實(shí)例處理的邏輯不一樣,這里我們需要將最快改變狀態(tài)的 Promise 結(jié)果作為 Promise.race 的結(jié)果,相對(duì)來(lái)說(shuō)就比較簡(jiǎn)單了,代碼如下:

          Promise.MyRace?=?function?(promises)?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????//?這里不需要使用索引,只要能循環(huán)出每一項(xiàng)就行
          ????for?(const?item?of?promises)?{
          ??????Promise.resolve(item).then(resolve,?reject)
          ????}
          ??})
          }
          復(fù)制代碼

          測(cè)試案例

          還是剛才幾個(gè)案例,咱就不重復(fù)寫(xiě)了??

          //?p1無(wú)延時(shí),p2延時(shí)1s,p3延時(shí)2s
          Promise.MyRace([p1,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p1

          //?p4無(wú)延時(shí)reject
          Promise.MyRace([p4,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p4?rejected
          ??
          //?p5?延時(shí)1.5秒reject,p2延時(shí)1s
          Promise.MyRace([p5,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?1s后打印:?p2?延時(shí)一秒
          復(fù)制代碼

          可以看到,結(jié)果與原生的 Promise.race 是一致的,成功!

          Promise.any

          Promise.anyPromise.all 可以看做是相反的。Promise.any 中只要有一個(gè) Promise 實(shí)例成功就成功,只有當(dāng)所有的 Promise 實(shí)例失敗時(shí) Promise.any 才失敗,此時(shí)Promise.any 會(huì)把所有的失敗/錯(cuò)誤集合在一起,返回一個(gè)失敗的?promise`AggregateError`[4]類(lèi)型的實(shí)例。MDN 上說(shuō)這個(gè)方法還處于試驗(yàn)階段,如果 node 或者瀏覽器版本過(guò)低可能無(wú)法使用,各位看官自行測(cè)試下。

          原生 Promise.any 測(cè)試

          const?p1?=?Promise.resolve('p1')
          const?p2?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p2?延時(shí)一秒')
          ??},?1000)
          })
          const?p3?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p3?延時(shí)兩秒')
          ??},?2000)
          })

          const?p4?=?Promise.reject('p4?rejected')

          const?p5?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????reject('p5?rejected?延時(shí)1.5秒')
          ??},?1500)
          })

          //?所有?Promise?都成功
          Promise.any([p1,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p1
          ??
          //?兩個(gè)?Promise?成功
          Promise.any([p1,?p2,?p4])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p1

          //?只有一個(gè)延時(shí)成功的?Promise
          Promise.any([p2,?p4,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p2?延時(shí)1秒

          //?所有?Promise?都失敗
          Promise.any([p4,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?AggregateError:?All?promises?were?rejected
          復(fù)制代碼

          可以看出,如果 Promise.any 中有多個(gè)成功的 Promise 實(shí)例,則以最快成功的那個(gè)結(jié)果作為自身 resolve 的結(jié)果。

          OK,理論存在,實(shí)踐開(kāi)始

          手寫(xiě)Promise.any

          1. 依葫蘆畫(huà)瓢,咱們先寫(xiě)出 `Promise.any` 的整體結(jié)構(gòu):
          Promise.MyAny?=?function?(promises)?{
          ??return?new?Promise((resolve,?reject)?=>?{
          ????promises.forEach((item,?i)?=>?{

          ????})
          ??})
          }
          復(fù)制代碼
          1. 這里跟`Promise.all` 的邏輯是反的,咱們需要收集 `reject` 的 `Promise`,也需要一個(gè)數(shù)組和計(jì)數(shù)器,用計(jì)數(shù)器判斷是否所有的 `Promise` 實(shí)例都失敗。另外在收集失敗的 `Promise` 結(jié)果時(shí)咱需要打上一個(gè)失敗的標(biāo)記方便分析結(jié)果。
          Promise.MyAny?=?function?(promises)?{
          ??let?arr?=?[],
          ????count?=?0
          ??return?new?Promise((resolve,?reject)?=>?{
          ????promises.forEach((item,?i)?=>?{
          ??????Promise.resolve(item).then(resolve,?err?=>?{
          ????????arr[i]?=?{?status:?'rejected',?val:?err?}
          ????????count?+=?1
          ????????if?(count?===?promises.length)?reject(new?Error('沒(méi)有promise成功'))
          ??????})
          ????})
          ??})
          }
          復(fù)制代碼

          這里我沒(méi)有使用 MDN 上規(guī)定的 AggregateError 實(shí)例,手寫(xiě)嘛,隨心所欲一點(diǎn),寫(xiě)自己看著舒服的??

          測(cè)試案例

          //?所有?Promise?都成功
          Promise.MyAny([p1,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p1
          ??
          //?兩個(gè)?Promise?成功
          Promise.MyAny([p1,?p2,?p4])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p1

          //?只有一個(gè)延時(shí)成功的?Promise
          Promise.MyAny([p2,?p4,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?p2?延時(shí)1秒

          //?所有?Promise?都失敗
          Promise.MyAny([p4,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?//?沒(méi)有promise成功
          復(fù)制代碼

          Promise.allSettled

          有時(shí)候,咱代碼人總是會(huì)有點(diǎn)特殊的需求:如果咱希望一組 Promise 實(shí)例無(wú)論成功與否,都等它們異步操作結(jié)束了在繼續(xù)執(zhí)行下一步操作,這可如何是好?于是就出現(xiàn)了 Promise.allSettled。

          原生 Promise.allSettled 測(cè)試

          const?p1?=?Promise.resolve('p1')
          const?p2?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p2?延時(shí)一秒')
          ??},?1000)
          })
          const?p3?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????resolve('p3?延時(shí)兩秒')
          ??},?2000)
          })

          const?p4?=?Promise.reject('p4?rejected')

          const?p5?=?new?Promise((resolve,?reject)?=>?{
          ??setTimeout(()?=>?{
          ????reject('p5?rejected?延時(shí)1.5秒')
          ??},?1500)
          })

          //?所有?Promise?實(shí)例都成功
          Promise.allSettled([p1,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?
          //?[
          //???{?status:?'fulfilled',?value:?'p1'?},
          //???{?status:?'fulfilled',?value:?'p2?延時(shí)一秒'?},
          //???{?status:?'fulfilled',?value:?'p3?延時(shí)兩秒'?}
          //?]

          //?有一個(gè)?Promise?失敗
          Promise.allSettled([p1,?p2,?p4])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))
          //?[
          //???{?status:?'fulfilled',?value:?'p1'?},
          //???{?status:?'fulfilled',?value:?'p2?延時(shí)一秒'?},
          //???{?status:?'rejected'?,?value:?'p4?rejected'?}
          //?]

          //?所有?Promise?都失敗
          Promise.allSettled([p4,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))
          //?[
          //???{?status:?'rejected',?reason:?'p4?rejected'?},
          //???{?status:?'rejected',?reason:?'p5?rejected?延時(shí)1.5秒'?}
          //?]
          復(fù)制代碼

          可以看到,與 Promise.any 類(lèi)似,Promise.allSettled 也給所有收集到的結(jié)果打上了標(biāo)記。而且 Promise.allSettled 是不會(huì)變成 rejected 狀態(tài)的,不管一組 Promise 實(shí)例的各自結(jié)果如何,Promise.allSettled 都會(huì)轉(zhuǎn)變?yōu)?fulfilled 狀態(tài)。

          OK,理論存在,實(shí)踐開(kāi)始

          手寫(xiě) Promise.allSettled

          咱就是說(shuō),得用個(gè)數(shù)組把所有的 Promise 實(shí)例的結(jié)果(無(wú)論成功與否)都收集起來(lái),判斷收集完了(所有 Promise 實(shí)例狀態(tài)都改變了),咱就將這個(gè)收集到的結(jié)果 resolve 掉。收集成功 Promise 結(jié)果的邏輯咱們?cè)?Promise.all 中實(shí)現(xiàn)過(guò),收集失敗 Promise 結(jié)果咱們?cè)?Promise.any 中處理過(guò)。這波,這波是依葫蘆畫(huà)瓢——照樣。

          Promise.MyAllSettled?=?function?(promises)?{
          ??let?arr?=?[],
          ????count?=?0
          ??return?new?Promise((resolve,?reject)?=>?{
          ????promises.forEach((item,?i)?=>?{
          ??????Promise.resolve(item).then(res?=>?{
          ????????arr[i]?=?{?status:?'fulfilled',?val:?res?}
          ????????count?+=?1
          ????????if?(count?===?promises.length)?resolve(arr)
          ??????},?(err)?=>?{
          ????????arr[i]?=?{?status:?'rejected',?val:?err?}
          ????????count?+=?1
          ????????if?(count?===?promises.length)?resolve(arr)
          ??????})
          ????})
          ??})
          }
          復(fù)制代碼

          這代碼,邏輯上雖說(shuō)沒(méi)問(wèn)題,但各位優(yōu)秀的程序員們肯定是看不順眼的,怎么會(huì)有兩段重復(fù)的代碼捏,不行,咱得封裝一下。

          Promise.MyAllSettled?=?function?(promises)?{
          ??let?arr?=?[],
          ????count?=?0
          ??return?new?Promise((resolve,?reject)?=>?{
          ????const?processResult?=?(res,?index,?status)?=>?{
          ??????arr[index]?=?{?status:?status,?val:?res?}
          ??????count?+=?1
          ??????if?(count?===?promises.length)?resolve(arr)
          ????}

          ????promises.forEach((item,?i)?=>?{
          ??????Promise.resolve(item).then(res?=>?{
          ????????processResult(res,?i,?'fulfilled')
          ??????},?err?=>?{
          ????????processResult(err,?i,?'rejected')
          ??????})
          ????})
          ??})
          }
          復(fù)制代碼

          perfect,俗話(huà)說(shuō)得好:沒(méi)病走兩步。老樣子,給代碼跑幾個(gè)案例。

          測(cè)試案例

          //?所有?Promise?實(shí)例都成功
          Promise.MyAllSettled([p1,?p2,?p3])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))?
          //?[
          //???{?status:?'fulfilled',?value:?'p1'?},
          //???{?status:?'fulfilled',?value:?'p2?延時(shí)一秒'?},
          //???{?status:?'fulfilled',?value:?'p3?延時(shí)兩秒'?}
          //?]

          //?有一個(gè)?MyAllSettled?失敗
          Promise.allSettled([p1,?p2,?p4])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))
          //?[
          //???{?status:?'fulfilled',?value:?'p1'?},
          //???{?status:?'fulfilled',?value:?'p2?延時(shí)一秒'?},
          //???{?status:?'rejected'?,?value:?'p4?rejected'?}
          //?]

          //?所有?MyAllSettled?都失敗
          Promise.allSettled([p4,?p5])
          ??.then(res?=>?console.log(res))
          ??.catch(err?=>?console.log(err))
          //?[
          //???{?status:?'rejected',?reason:?'p4?rejected'?},
          //???{?status:?'rejected',?reason:?'p5?rejected?延時(shí)1.5秒'?}
          //?]
          復(fù)制代碼

          致此,大功告成,我可以驕傲地對(duì)媽媽說(shuō):“媽媽?zhuān)以僖膊慌?Promise.all”了

          結(jié)語(yǔ)

          這次字節(jié)飛書(shū)面試對(duì)我來(lái)說(shuō)是一個(gè)巨大的機(jī)遇,第一次體驗(yàn)面大廠(chǎng)的感覺(jué),可能有暴躁老哥要說(shuō)了:“字節(jié)面試題就這?你是水文章騙贊的吧”。害,沒(méi)辦法,主要是我太菜了,從代碼不知為何物到現(xiàn)在前端學(xué)習(xí)者,爾來(lái)8月右一周矣,水平確實(shí)比較次,面試官比較和善,就沒(méi)有為難我,問(wèn)的問(wèn)題都比較基礎(chǔ)。但我仍然收獲頗豐,感謝字節(jié)團(tuán)隊(duì),感謝前端這個(gè)包容、進(jìn)步的環(huán)境,我會(huì)好好總結(jié)這次面試,盡可能地提升自己,加油!

          作者:滑稽鴨

          https://juejin.cn/post/7069805387490263047

          祝 :2022 年暴富!萬(wàn)事如意!

          點(diǎn)贊和在看就是最大的支持,比心??

          瀏覽 23
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  а√天堂中文在线资源8 | 自拍视频二区 | 69视频网站 | 丁香六月婷婷综合缴 | henhengan |