當前位置:成語大全網 - 漢語詞典 - JS的異步遍歷,真的能寫出來嗎?

JS的異步遍歷,真的能寫出來嗎?

有時我們需要遍歷數組的元素,並將它們傳遞給異步函數來執行。異步書寫方法容易出錯。讓我們來看看壹些錯誤。

假設我們有壹個異步方法sleepPromise,其形式如下:

這裏為了演示方便,用setTimeout寫了壹個promise形式的睡眠方法。傳入的t是延遲執行的時間,msg是信息內容。

在實際開發中,異步方法可能是傳入用戶的好友id來查找數據庫,得到簡單的好友信息。

假設我們需要在下面代碼的註釋位置下面寫壹個異步的方便實現。

通常前端壹看到要遍歷的數組就會使用forEach。如果您不夠成熟,您可以編寫以下實現:

輸出結果是:

這種寫法不對,其實就是把遍歷寫成同步。

有什麽問題?forEach本身不支持異步編寫,所以如果在ForEach方法前面加上await關鍵字是無效的,因為裏面沒有處理異步的邏輯。

ForEach是ES5的API,比ES6的承諾要早很多。為了向後兼容,ForEach將來將不支持異步處理。

所以forEach的執行不會阻塞loopAsync之後的代碼,所以會導致阻塞失敗,先輸出[end]。

使用普通的for循環編寫,await的外層函數仍然是loopAysnc方法,可以正確保存阻塞代碼。

但是這裏的問題是這些異步方法的執行是串行的。可見總* * *執行了6 s。

如果我們的請求有順序依賴,這樣寫是沒有問題的。

但如果我們的場景是根據用戶id數組從數據庫中找到對應的用戶名,我們的時間復雜度是O(n),這是不合理的。

此時,我們需要將其重寫為並行異步,並且我們必須確保在執行下壹步之前執行所有異步。我們可以使用Promise.all()。

首先我們需要根據tasks數組生成對應的promise對象數組,然後傳入Promise.all方法執行。

這樣,這些異步方法將被同時執行。當所有的異步都被執行後,代碼將被執行。

輸出結果如下:

三秒鐘就搞定了。太強了。

如前所述,forEach底層沒有實現異步處理,導致阻塞失敗,我們不妨實現壹個簡單的支持異步的forEach。

並行實現:

串行實現:

用法:

簡單總結壹下。

壹般來說,我們經常使用Promise.all的並行執行異步方法,常見於數據庫查找壹些id對應的數據的場景。

for循環的串行編寫適用於多個異步和依賴的情況,比如尋找最終裁判。

ForEach純粹是個錯誤,除非妳不需要使用async/await。