簡體   English   中英

為什么第二個JS異步函數調用要等待第一個完成?

[英]Why does 2nd JS async function call wait for 1st to finish?

我的印象是,除非使用await關鍵字,否則不會阻止對異步函數的調用。 但是對於以下代碼:

編輯:我正在編輯示例,以更好地說明我的問題。

function sum1Through(n) {
    console.log('Starting computation for ' + n);
    let result = 0;
    for (let i = 1; i <= n; i++) {
      result += i;
    }
    console.log('Finished computation for ' + n);
    return result;
}

function asyncSum1Through(n) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(sum1Through(n));
        }, 0);
    });
}

asyncSum1Through(1000000000);
asyncSum1Through(2);
sum1Through(3);

輸出順序為:

Starting computation for 3
Finished computation for 3
Starting computation for 1000000000
Finished computation for 1000000000
Starting computation for 2
Finished computation for 2

為什么第二個呼叫被阻塞,直到第一個呼叫完成,而第三個呼叫沒有完成?

使用異步函數並不意味着它將“異步”執行。 它提供的是,使用等待可以將其暫停並等待某事。

異步功能

異步函數可以包含一個await表達式,該表達式暫停異步函數的執行並等待傳遞的Promise的分辨率,然后恢復異步函數的執行並返回解析的值。

函數中的所有代碼都是同步的,並在調用返回promise之前立即運行。 在稍后運行await之后,您實際上需要await一些東西才能擁有代碼。

異步函數不會啟動線程或並行運行任何東西,它們也不能阻止其調用者。 它們只是提供一種簡單的語法來編寫帶有承諾的順序代碼。

如果端點是console.log()那么顯然“所有功能”都是異步的。 不僅是因為一個原因,還有兩個原因。

  1. asyncSum1Through()函數中,在setTimeout的回調中調用console.log()指令,從而使它們被異步調用。
  2. 即使在sum1Through(3)中,默認情況下也會異步調用console.log() sum1Through(3)函數,但這不是我們關心的問題。

因此輸出非常“符合預期”。 而最后一條指令; 即... sum1Through(3); 它恰好是同步的,直到首先出現console.log()為止(因為console.log()注冊到事件隊列中),然后其他的按照它們進入事件隊列的順序進行。

實際上,如果您沒有將setTimeout()混入您的Promise中,它可能會更加令人費解,但這完全是另一個稱為微任務的主題。

注意:哦..! 如果你的問題是 在這兩個asnc函數中,為什么第二個要等待第一個完成,而第二個要花費更少的時間呢? 然后,您應該了解異步任務對CPU線程當前正在消耗的CPU工作沒有任何特權。 JS是一種單線程語言,任何有權首先渲染的任務都必須在下一個任務之前先完成。 JS中的異步性是指當其他任務閑置等待不擁有CPU線程JS的IO操作時,它們授予優先級。

暫無
暫無

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

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