前言
Promise
是
es6
新出的文法,用來處理異步請求,解決之前沒有
Promise
時的回調地獄。
Promise
有幾個api,
Promise.resolve
,
Promise.reject
,
Promise.all
,
Promise.race
。關于多個異步的處理我們可以用
Promise.all
,但
Promise.all
隻在所有的
promise
都
resolve
時才會調用
.then
中的成功回調。 有時候多個請求難免會有失敗的情況,我們想當
Promise.all
中的
promise
對象
reject
失敗時也能夠調用回調函數,這個時候應該怎麼做呢?
開搞
我們先來了解下
Promise.all
的用法。
Promise.all([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)])
.then(res => console.log(res),err=>console.log(err))
// [1, 2, 3]
Promise.all([Promise.reject(1), Promise.resolve(2), Promise.resolve(3)])
.then(res => console.log(res),err=>console.log(err))
// 1
Promise.all
中傳入的是多個
promise
對象組成的數組。數組中所有的
promise
成功時才會列印
res
,隻要有一個失敗就會列印
err
。
我們想要達到就算失敗也能列印所有的資訊,應該怎麼做呢?很簡單,用
.then
因為
.then
傳回的也是一個
promise
對象,不管是
resolve
還是
reject
都會執行
.then
。傳回
promise
對象後就變成
resovle
狀态了。
Promise.all([Promise.reject(1).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err })),
Promise.resolve(2).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err })),
Promise.resolve(3).then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err }))])
.then(res => console.log(res),err=>console.log(err))
//[ {status: "not ok", err: 1},{status: "ok", res: 2},{status: "ok", res: 3}]
這樣就列印出了所有的資訊,即便
Promise.all
中有
reject
狀态。
優化封裝
現在這種寫法很繁瑣,每個數組中的每個
promise
都要寫同樣的
.then
。我們可以把
.then
抽離出來。封裝成一個函數,然後用
map
方法,對每個
promise
.then
一下,然後傳回新的數組。
function handlePromise(promiseList) {
return promiseList.map(promise =>
promise.then((res) => ({ status: 'ok', res }), (err) => ({ status: 'not ok', err }))
)
}
這樣調用
promise.all
時,可以這麼寫:
Promise.all(handlePromise([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]))
.then(res => console.log(res),err=>console.log(err))
也是同樣的效果。
甚至我們可以寫一個
Promise.allSettled
方法:
Promise.allSettled2 = function (promiseList) {
return Promise.all(handlePromise(promiseList))
}
Promise.allSettled2 ([Promise.reject(1),Promise.resolve(2),Promise.resolve(3)]).then(res => console.log(res), err => console.log(err))
這就是
promise
新出的
allSettled
Api`,隻不過相容性不太好,不過沒事,看了這篇文章之後,我們可以自己封裝個一樣功能的api了。完結撒花。
