天天看點

promise的用法_Promise.all 的缺陷

前言

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了。完結撒花。

promise的用法_Promise.all 的缺陷