[英]Multiple await`s in one line (nested async calls)
我找不到關於一行中多個await
的含義或應該如何處理它們的任何好的信息。 所以我創建了以下測試代碼(在 Node 中執行):
async function resolveAfterNSeconds(n, value) { return new Promise((resolve) => { setTimeout(() => { resolve(value); }, n*1000); }); }; async function test(which) { const start = new Date().getTime(); let result; switch (which) { case 1: result = await resolveAfterNSeconds(10, await resolveAfterNSeconds(2, 'done')); break; case 2: result = await resolveAfterNSeconds(2, await resolveAfterNSeconds(10, 'done')); break; case 3: result = await resolveAfterNSeconds(10, resolveAfterNSeconds(2, 'done')); break; case 4: result = await resolveAfterNSeconds(2, resolveAfterNSeconds(10, 'done')); break; case 5: result = resolveAfterNSeconds(10, await resolveAfterNSeconds(2, 'done')); break; case 6: result = resolveAfterNSeconds(2, await resolveAfterNSeconds(10, 'done')); break; } const end = new Date().getTime(); console.log([which, result, (new Date().getTime()-start)/1000]); } test(1); // [1, 'done', 12], as expected test(2); // [2, 'done', 12], as expected test(3); // [3, 'done', 10], as expected (kind of) test(4); // [4, 'done', 10], but expected: [4, Promise, 2] test(5); // [5, Promise, 2], as expected test(6); // [6, Promise, 10], as expected
我想我確實理解為什么在第 3 種情況下,返回'done'
是'done'
而不是相應的Promise
- 到那時 2s 超時已經完成(我說得對嗎?)。
但是,我不明白情況 4:似乎一開始的await
也以某種方式與內部Promise
,否則,不應該在 2 秒后返回(而不是'done'
)這個Promise
嗎?
但是,如果外部await
實際上也與內部Promise
相關,這是否意味着情況 1 和 2 是無意義的,應該始終替換為情況 3 和 4(分別),以便兩個或更多一行中的await
從來沒有用?
我想我確實理解為什么在第 3 種情況下,返回的是“完成”而不是相應的 Promise - 到那時 2s 超時已經完成(我說得對嗎?)。
不,它與案例4相同。
但是,我不明白情況 4:似乎一開始的 await 也與內部 Promise 有某種關系,否則,不應該在 2 秒后返回(而不是“完成”)這個 Promise 嗎?
如果你用另一個承諾 (Y) 解決了一個承諾 (X),那么承諾 X 就會采用承諾 Y 的狀態。
但是,如果外部 await 實際上也與內部 Promise 相關,這是否意味着情況 1 和 2 是無意義的,應該始終替換為情況 3 和 4(分別),
不,他們有不同的行為。
如果您await
承諾 (Y) 並將其解析值用作創建另一個承諾 (X) 的函數的參數,則該函數將不會開始運行,直到 Y 已解析。
如果您不等待它,那么它將在Y
解析之前開始運行(因此包裝在 Promise 中的兩個操作可以並行運行)。
基本上, async/await
只是Promise
的包裝器。 如果您調用任何async
函數,它會返回 Promise,並使用await
調用它會停止執行主上下文並等待Promise
完成。 但是如果你在沒有await
情況下調用它,那么它將只是一個簡單的函數調用,Promise 將開始執行,但不會等待它的結束,其余代碼將同步執行。
所以在的情況下,4呼叫你的例子resolveAfterNSeconds
用await
創建圍繞一個承諾resolveAfterNSeconds(2, value)
和呼叫resolveAfterNSeconds(10, value)
的參數,而無需await
執行resolveAfterNSeconds(10, value)
同步,以使內什么線索Promise
作為第二個參數。
因此await resolveAfterNSeconds(2, value)
停止執行主上下文並在其中創建Promise
鏈,因此只有在整個Promise
鏈都被解析,並且Promise
鏈的結果done
時才會繼續執行 - 最后解析的值,這涉及到result
變量。
這就是為什么你done
價值;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.