我有一個簡短的 Node.js 腳本,我需要另一個包并從中呼叫異步函式,然后想要列印回傳值。如果我只是await從頂層回傳值,那么我會得到一個錯誤,說我只能await在異步函式本身內部使用。所以顯然要走的路是這樣的:
async function main() {
foo = await someOtherAsyncFunc();
console.log(foo);
}
main()
要么:
(async function() {
foo = await someOtherAsyncFunc();
console.log(foo);
})();
要么:
(async () => {
foo = await someOtherAsyncFunc();
console.log(foo);
})();
(歸功于聊天中的 VLAZ https://chat.stackoverflow.com/transcript/message/54186176#54186176)
這行得通 - 但我想進一步了解其背后的原因:我習慣于無法直接await從頂層使用。但是,我也習慣于呼叫一些特殊的庫函式來真正從頂層“冒險”進入異步。在 Python 中,請參見asyncio.run示例。需要await在異步函式內部有什么意義 - 如果我可以從頂層呼叫任何異步函式?那么為什么await在頂層也不能使用呢?
uj5u.com熱心網友回復:
頂級 await曾經不是一個東西,但現在在 ES6 模塊中是可能的。
頂級 await 過去不是一個東西,并且仍然不是模塊之外的東西的一個原因是它可能允許語法歧義。Async 和 await 是有效的變數名。模塊之外。如果非模塊腳本允許頂級等待,那么,如果不重新撰寫規范(并破壞向后兼容性),就會出現決議器無法確定特定實體是否是await變數名的情況,或者被用作等待其右側的 Promise 解決的語法。
為了避免任何歧義的可能性,決議器在決議一段代碼時,本質上需要有標志來指示await在任何給定點作為識別符號是否有效,或者它是否作為異步語法有效,并且這兩者絕不能相交。
模塊腳本允許頂級等待(現在),因為在它們中一直禁止使用等待作為識別符號,因此沒有語法歧義。
相比之下,.then在頂層使用的問題為零,因為它在任何情況下都不會導致任何歧義。
為什么它不只是回傳一個永遠不會執行的 Promise,因為它沒有得到等待?
承諾并沒有真正“執行”。它們可以被構建,或者等待完成,或者等待拒絕。如果您有一個 Promise,那么您已經有一些正在進行的代碼(可能)最終會導致為 Promise 分配一個履行值。
懸掛 Promise 在語法上是允許的——決議為 Promises 但不與其他地方互動的值。(這是有道理的——每一個 .then或.catch產生一個新的 Promise。如果每一個 Promise 都必須被其他東西使用,你最終會得到無限的倒退。)
正在做
(async () => {
foo = await someOtherAsyncFunc();
console.log(foo);
})();
本質上是語法糖
someOtherAsyncFunc()
.then((foo) => {
console.log(foo);
});
沒有必要在其中任何一個的末尾添加任何其他內容。(盡管建議在懸空的 Promise中添加 a .catch,這樣就不會發生未處理的拒絕)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/448915.html
標籤:javascript 节点.js 异步 异步等待
