我們知道async函式會隱式回傳一個 Promise。但我有一個純粹迂腐的問題。如果我async明確回傳一個 Promise,我應該輸入一個關鍵字嗎?
這是:
const wait = async ms => new Promise(
resolve => setTimeout(resolve, ms)
);
有什么不同嗎?
const wait = ms => new Promise(
resolve => setTimeout(resolve, ms)
);
我相信在技術上它們是相同的。這兩種定義這種功能的方法背后是否有任何風格指南或官方推薦?
uj5u.com熱心網友回復:
我認為使用async函式有四個主要原因:
- 您想使用
await. - 您希望它自動捕獲同步例外并將它們轉換為被拒絕的承諾。
- 您希望它始終回傳一個承諾,而不管您的函式實際回傳什么。
- 你喜歡這樣一個事實,即讓函式
async讓查看代碼的呼叫者清楚地知道函式總是回傳一個承諾——本質上是自我記錄。
因此,如果您不使用await并且不需要第 2 點并且您已經手動回傳了一個承諾,那么實際上不需要將該函式宣告為async.
關于以上幾點的更多想法。
點#1要求async,如果你要使用await。沒有其他辦法解決它。
第 2 點和第 3 點實際上只是編程方便。如果您捕獲自己的同步例外或確定沒有同步例外并且您正在控制所有代碼路徑以回傳承諾,則async沒有必要。
如果您的代碼同時具有同步代碼路徑和異步代碼路徑,則第 2 點和第 3 點都可能出現,例如檢查快取并回傳一個值,如果它存在于快取中,如果不在快取中,則創建一個獲取值的網路請求。如上所述,這可以在沒有 的情況下手動編碼async,但有時代碼可以更簡單一些,async因為它會自動捕獲您的同步例外并自動將回傳值包裝在承諾中。
第 4 點只是一種編碼風格偏好。如果您喜歡制作 function 的“自我記錄”方面async,您可以這樣做以表明它總是回傳一個承諾。
而且,對于任何對async函式如何在內部作業并經過多年優化的技術細節感興趣的人,這是一篇關于該主題的相當深入的文章:關于快速異步的 V8 博客。
uj5u.com熱心網友回復:
在給定的示例中,async關鍵字本質上只是將回傳值包裝在Promise.resolve(). 請參閱異步函式檔案。
所以一方面你有:
const wait = ms => new Promise(resolve => setTimeout(resolve, ms));
另一方面,您有:
const wait = async ms => new Promise(resolve => setTimeout(resolve, ms));
// is similar to
const wait = ms => Promise.resolve(new Promise(resolve => setTimeout(resolve, ms)));
它們本質上是相同的,我個人會選擇沒有async關鍵字的變體。
筆記:
即使 async 函式的回傳值表現得好像它被包裹在 a 中
Promise.resolve,但它們并不等效。異步函式將回傳不同的參考,而
Promise.resolve如果給定值是承諾,則 回傳相同的參考。當您想要檢查異步函式的承諾和回傳值的相等性時,這可能是一個問題。
const p = new Promise((res, rej) => { res(1); }) async function asyncReturn() { return p; } function basicReturn() { return Promise.resolve(p); } console.log(p === basicReturn()); // true console.log(p === asyncReturn()); // false
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/344622.html
