簡體   English   中英

在異步函數中調用同步函數

[英]Invoking synchronous function in asynchronous function

我在理解 JavaScript 中的異步函數如何工作時遇到問題。 讓我們看下面的代碼:

async () => {
      console.log(1);
      setTimeout(() => console.log(2)
        , 2000)
      console.log(3);
}

我希望在 async 中調用同步函數應該在執行進一步的代碼之前阻塞線程。 所以我希望得到1 -> 2 -> 3而不是我得到1 -> 3 -> 2 無法解釋為什么會發生這種情況以及如何阻止線程接收輸出1 -> 2 -> 3 我正在將 Node 12 與無服務器框架一起使用。

async本身不會像您期望的那樣等到setTimeout執行完成。 正如您可以從文檔中閱讀的那樣 - 在這里找到async

異步函數可以包含一個 await 表達式,該表達式暫停異步函數的執行以等待傳遞的 Promise 的解析,然后恢復async函數的執行並評估為解析的值。

剛剛構建了一個快速示例來查看asyncawait解決方案之間的區別,並且只使用setTimeout就像在您的示例中一樣。

考慮以下示例:

 const getPromise = async () => { return new Promise((resolve) => { setTimeout(resolve, 3000); }); } const run = async () => { console.log('run started'); setTimeout(() => console.log('setTimeout finised'), 2000); console.log('setTimeout started'); const promise = await getPromise(); console.log('Promise resolved'); console.log('run finished'); } run();

步驟說明:

  1. 記錄函數run執行開始
  2. 將事件附加到setTimeout將在大約 2 秒內完成
  3. 登錄到setTimeout啟動的控制台
  4. 使用getPromise函數和await關鍵字創建承諾等待resolve
  5. 在約 2 秒內setTimeout記錄它已完成
  6. Promise的約 3 秒內,調用了resolve函數
  7. run函數在resolve和記錄后完成其執行。

我希望能幫助您理解這部分代碼。

我希望在 async 中調用同步函數應該在執行進一步的代碼之前阻塞線程。

它確實

所以我希望得到 1 -> 2 -> 3 而不是我得到 1 -> 3 -> 2。

setTimeout不是同步的。 它非常明確地用於排隊一個函數以在一段時間后運行。

找不到解釋為什么會發生這種情況以及如何阻止線程接收輸出 1 -> 2 -> 3。

你本身不能。

最接近的方法是用一個循環替換setTimeout直到一段時間過去……但這會很糟糕(它會為初學者鎖定 UI)。

如果您只想按順序運行三個日志,則將setTimeout替換為返回承諾的內容,然后await它(這將使異步函數進入睡眠狀態並讓任何其他代碼繼續運行,直到承諾解決)。

 const timeout = function() { return new Promise(function(res) { setTimeout(() => { console.log(2); res(); }, 2000) }) }; const x = async() => { console.log(1); await timeout(); console.log(3); } x();

暫無
暫無

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

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