簡體   English   中英

等待同步函數是否同步返回值?

[英]Does awaiting a synchronous function synchronously return a value?

我從一個我不熟悉的內部實用程序庫中導入了一個函數。 這個庫沒有文檔,我只是假設它是異步的,因為它的名字是getUserDetails 我以為它在做一個http請求。

我在這樣的異步函數中使用它

async function getAllUserInfo(event) {
    const details = await getUserDetails(event);
    // other stuff
}

我的假設是錯誤的。 一位同事指出這不是異步的。 我最終改變了它,但是當我錯誤地使用它時它仍然有效。 我能夠等待同步函數並返回正確的數據。

我的問題是關於它是如何工作的。 是否在同步函數上添加 await 使其在下一個滴答聲中解析,還是像同步函數那樣立即返回?

它起作用是因為await不需要它的操作數是一個承諾! 如果它不是承諾,則返回等待表達式的值。

請參閱await 運算符的文檔

重要的部分是:

 [rv] = await expression;
  • expression : 一個Promise或任何要等待的值。
  • rv :返回 promise 的已履行值,如果它不是Promise則返回值本身。

在您的情況下, getUserDetails沒有返回承諾,而是一些常規用戶詳細信息,因此await表達式僅返回這些詳細信息,就好像操作員根本不在那里一樣。

但是,即使getUserDetails是同步的,在 async 函數中在它前面加上await將放棄對其調用者的控制,並且稍后選擇await之后的“回調部分”。 這是一個示例腳本:

function f() {
  console.log('In f');
}

async function g() {
  console.log('Starting g');
  await f();
  console.log('Finishing g');
}

console.log('Starting the script')
g();
console.log('Finishing the script')

注意腳本的輸出:

$ node asynctest.js 
Starting the script
Starting g
In f
Finishing the script
Finishing g

注意await調用如何“暫停” g,直到主塊完成才能恢復! 所以await確實有效果。 如果您沒有將等待放在那里,那么您會在“完成腳本”之前看到“完成 g”。 試試看!

順便說一句,效果的原因是,即使可以給await一個不產生承諾的表達式,JS 也會將非承諾操作數轉換為立即解析為該值的承諾。 所以仍然創建了一個promise,await之后的部分被視為回調,在當前執行流程完成之前不能運行。

如果您等待一個不是承諾的值,它會通過使用Promise.resolve轉換為已解決的承諾。

 function sync(){ return 1 } (async ()=>{ const v = await sync(); console.log(v) })(); (async ()=>{ const v = await Promise.resolve(sync()); console.log(v) })()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM