簡體   English   中英

為什么我的 async/await 示例不起作用?

[英]Why does my async/await example not work?

我很難理解async/await的整個概念,並且花了幾個小時閱讀文檔並試圖讓一個例子起作用。 但我仍然不明白為什么這個小例子不起作用。

我想要的結果是document.body.innerHTML包含文本“123”,因為doFirst()應該在doSomething()完成之前完成運行。

但是我總是得到“132”,就好像我根本沒有使用過異步/等待一樣。 我究竟做錯了什么?

 async function doFirst() { document.body.innerHTML = document.body.innerHTML + "1"; setTimeout(function() { document.body.innerHTML = document.body.innerHTML + "2"; }, 500); } async function doSomething() { await doFirst(); document.body.innerHTML = document.body.innerHTML + "3"; } doSomething();

很抱歉再次發布此問題,上次我發布此問題時,它被標記為重復。 所以這次我想澄清一下,我不是在尋找任何能告訴我如何正確操作的答案,而是想解釋為什么我的代碼不起作用。

這是因為doFirst()返回一個 promise ,它在計時器用完之前解決。 與您的預期相反, setTimeout不會暫停腳本執行。

為了確保doFirst()在計時器用完后解析,您需要將整個 function 包裝在Promise object 中。 計時器用完后將調用resolve()方法,如下所示:

 function doFirst() { return new Promise(resolve => { document.body.innerHTML = document.body.innerHTML + "1"; setTimeout(function() { document.body.innerHTML = document.body.innerHTML + "2"; resolve(); }, 500); }); } async function doSomething() { await doFirst(); document.body.innerHTML = document.body.innerHTML + "3"; } doSomething();

If you want to avoid callback hell , an cleaner way is to simply create a utility function that resolves a promise after a setTimeout, then you can await on the promise returned from that function to be resolved before printing "2" into the DOM:

 // Utility function that resovles a promise after a given duration function sleep(duration) { return new Promise(resolve => setTimeout(resolve, duration)); } async function doFirst() { document.body.innerHTML = document.body.innerHTML + "1"; await sleep(500); document.body.innerHTML = document.body.innerHTML + "2"; } async function doSomething() { await doFirst(); document.body.innerHTML = document.body.innerHTML + "3"; } doSomething();

看看下面的代碼:


async function doFirst() {
  document.body.innerHTML = document.body.innerHTML + "1";
  return myAsyncFunc(500)
}

function myAsyncFunc(delay) {
    return new Promise(resolve => setTimeout(function() {
            document.body.innerHTML = document.body.innerHTML + "2"
            resolve();
        }, delay));
}

async function doSomething()
{
  await doFirst();
  document.body.innerHTML = document.body.innerHTML + "3";
}

你在做什么錯?

您沒有在doFirst()中返回 promise ,因此操作不是異步的(簡而言之,您的代碼doSomething()不會等待doFirst()完成並移動到行document.body.innerHTML = document.body.innerHTML + "3"; )

筆記:

  1. document.body.innerHTML = document.body.innerHTML + "1"; 立即運行並返回myAsyncFunc (基本上返回Promise )。

  2. 500 毫秒后, setTimeout執行,因此document.body.innerHTML = document.body.innerHTML + "2"運行。 之后,下一行return resolve()返回,這標志着Promise完成。

  3. 一旦返回resolveawait就結束了,因此添加了“3”

我認為您可能對async關鍵字的作用有誤解。 它並沒有神奇地將 function 更改為異步,盡管它的名字。 它只做以下兩件事:

  1. 允許在 function 主體內部使用await
  2. 確保 function 返回 Promise。

但只有當這兩者一起使用時,它才真正有用。 一個沒有await的異步 function 根本不需要異步。

您的示例 function doFirst不使用await ,因此它基本上等同於以下內容:

function doFirst() {
    document.body.innerHTML = document.body.innerHTML + "1";
    setTimeout(function() {
        document.body.innerHTML = document.body.innerHTML + "2";
    }, 500);
    return Promise.resolve(undefined);
}

如您所見,這段代碼沒有任何異步。 Promise.resolve返回一個可以立即解析為給定值的 promise。 這意味着在doSomething中使用await doFirst()實際上不會等待任何內容,因為 promise 已經解決。

你想讓doFirst做的是返回一個 promise 直到setTimeout回調執行后才會解決。 不幸的是setTimeout不返回 promise 所以你需要手動創建一個:

function doFirst() {
    document.body.innerHTML = document.body.innerHTML + "1";
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            document.body.innerHTML = document.body.innerHTML + "2";
            resolve();
        }, 500);
    });
}

您可能會注意到這里不需要async關鍵字。 這是因為 function 不使用await並且已經返回 promise。 doSomething仍然可以使用await doFirst()因為await適用於任何 promise,而不僅僅是在調用異步函數時。

暫無
暫無

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

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