Promise的鏈式呼叫和axios處理高併發

2022-07-07 19:06:14 字數 3440 閱讀 4369

最近在專案中又遇到了乙個介面的請求需要依賴另乙個介面的請求結果和處理高併發的場景了,所以即興在這裡簡單總結和分享下,歡迎指正和補充。

一、promise 簡要回顧

promise 是乙個建構函式,作為 es6 中最重要的特性之一,它有 all、resolve、reject、race ... 眼熟的方法,原型上有 then、catch 等同樣熟悉的方法,所以 new promise 返回的 promise 物件也有 then、catch 方法。

我們知道 promise 能幫助我們避免**地獄,可以理解成 promise 就是對於**函式的另一種寫法。雖然從表面上看,promise 能夠簡化層層**的寫法,但 promise 通過傳遞狀態的方式來使得**函式能夠及時呼叫,它比傳統的**函式和事件更簡單、更靈活。

以下以定時器模擬,對於多個請求情況的處理,例項化如下:

function

getp1() , 1000);

});}​

function

getp2() , 2000);

});}​

function

getp3() , 3000);

});}

二、使用場景 ①僅呼叫,不考慮其他,只要執行了即可。

getp1().then(res1 =>)

getp2().then(res2 =>)

......

三、使用場景 ②先呼叫 p1,再呼叫 p2,再呼叫 p3 ......

getp1()

.then(res1 =>)

.then(res2 =>)

.then(res3 =>)

執行結果如下:

從結果可以看出,像這樣按順序,每隔一秒輸出每個非同步**中的內容,就是鏈式呼叫。

具體**執行順序:

1)第一步呼叫 getp1 函式,執行完成返回乙個 promise,狀態是成功,即resolve('getp1呼叫成功'),然後將引數 "getp1呼叫成功" 傳遞並執行第乙個 then;

2)第乙個 then 接收 "getp1呼叫成功",執行 then 的**,**中呼叫了 getp2,執行並返回成功狀態的 promise,然後給下乙個 then 傳遞引數 "getp2呼叫成功";

3)第二個 then 接收 "getp2呼叫成功",執行 then 的**,**中呼叫了 getp3,執行並返回成功狀態的 promise,然後給下乙個 then 傳遞引數 "getp3呼叫成功";

4)最後乙個 then 接收 "getp3呼叫成功",執行**,然後輸出 "getp3呼叫成功"。

注意:

四、reject 的使用

前面的例子只有執行成功的**,沒有失敗的情況,可以通過 reject 把 promise 的狀態置為 rejected(**丟擲異常或出錯了),然後在 .catch 方法中捕捉到執行失敗情況的**。例如:

function

getp2() , 2000);

});}​

getp1()

.then(res1 =>)

.then(res2 =>)

.then(res3 =>)

.catch(err =>)

執行結果如下:

每乙個.then 都是銜接著上乙個 promise 的,.catch 會捕捉任意乙個 promise 的 reject 狀態。當 .then 返回乙個 rejected 的 promise 時,後面就不執行了,丟擲的錯誤也會被 .catch 方法捕獲。

五、使用場景 ③

p3 的呼叫依賴 p1 和 p2 的執行結果

這就用到了 promise 的 all 方法,它提供了並行執行非同步操作的能力,並且在所有非同步操作執行完後才執行**。

promise.all 接收乙個 promise 物件的陣列作為引數,當這個陣列裡的所有 promise 物件全部變為 resolve 或 reject 狀態的時候,它才會去呼叫 .then 方法。看下面的例子(此處仍使用上面定義好的getp1、getp2、getp3 這三個函式):

promise

.all([getp1(), getp2(), getp3()])

.then(res =>);

上面**的輸出結果如下:

有了 all 方法,我們就可以並行執行多個非同步操作,並且在乙個**中處理所有的返回資料,就是上面的 res。比如開啟網頁時,需要預先載入用到的資源如或靜態檔案,等所有的都載入完後,我們再進行頁面的初始化。

如果把 getp2 的 promise 狀態設定為 reject,執行如下**:

promise.all([getp1(), getp2(), getp3()])

.then(res =>)

.catch(err =>)

執行結果如下:

注意:

六、promise.all() 

方法的使用情景:

七、axios 處理高併發

相似的,在官方 axios 中,提供了 axios.all()和 axios.spread()兩個函式,用於處理同時傳送多個併發請求,在多個請求都完成後再執行一些邏輯。此處借用官方文件的示例:

function

getuseraccount()

​function

getuserpermissions()

​axios.all([getuseraccount(), getuserpermissions()])

.then(

axios.spread((acct, perms) =>)

);

注意:可以看到 axios.all() 方法與 promise.all() 方法,不管在使用方式還是傳參形式都是一模一樣的。

promise的非同步鏈式呼叫

場景 淘公尺 乾淨的公尺下鍋 蒸公尺飯 吃公尺飯 這幾個步驟是乙個接著乙個執行,也就是只有前面的做完後,才會去做後面的.並且每一步都需要用一部分時間去執行.1 function deal task,time time 8 9 1011 執行後會每隔一秒顯示 淘公尺 公尺下鍋 蒸公尺飯 吃公尺飯 12...

Promise 巢狀鏈式呼叫的問題

promise鏈式呼叫巢狀的問題,哈哈哈 雖然這個問題在正常開發中應該不會遇到,但是誰讓咱們是程式設計師呢,就是喜歡搞事情,這個問題就是搞promise鏈式巢狀呼叫 new promise function promise1 resolve,reject then function then1 th...

Promise鏈式呼叫 終止或取消

promise 分兩種方法,then成功,catch失敗 let promise new promise function resolve,reject promise.then function val then function val catch function val 第三種方法有點粗暴,...