字節(jié)飛書(shū)面試——請(qǐng)實(shí)現(xiàn) Promise.all
前言
金三銀四,身為大四即將成為畢業(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)鍵字:
Promise.all的返回值是一個(gè)新的Promise實(shí)例。Promise.all接受一個(gè)可遍歷的數(shù)據(jù)容器,容器中每個(gè)元素都應(yīng)是Promise實(shí)例。咱就是說(shuō),假設(shè)這個(gè)容器就是數(shù)組。數(shù)組中每個(gè) Promise實(shí)例都成功時(shí)(由pendding狀態(tài)轉(zhuǎn)化為fulfilled狀態(tài)),Promise.all才成功。這些Promise實(shí)例所有的resolve結(jié)果回按原來(lái)的順序集合在一個(gè)數(shù)組中作為Promise.all的resolve的結(jié)果。數(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ù)制代碼
注意
上面 p4 和 p5 在未傳入 Promise.all 時(shí)需要注釋掉,因?yàn)橐粋€(gè)調(diào)用了 reject 的 Promise 實(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
`Promise.all` 接受一個(gè)數(shù)組,返回值是一個(gè)新的 `Promise` 實(shí)例
Promise.MyAll?=?function?(promises)?{
??return?new?Promise((resolve,?reject)?=>?{
??})
}
復(fù)制代碼
數(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ù)制代碼
將收集到的結(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ù)制代碼
最后就是處理失敗的情況了,這里有兩種寫(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.race、Promise.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.any 與 Promise.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
依葫蘆畫(huà)瓢,咱們先寫(xiě)出 `Promise.any` 的整體結(jié)構(gòu):
Promise.MyAny?=?function?(promises)?{
??return?new?Promise((resolve,?reject)?=>?{
????promises.forEach((item,?i)?=>?{
????})
??})
}
復(fù)制代碼
這里跟`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)贊和在看就是最大的支持,
比心??
