[英]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";
)
筆記:
document.body.innerHTML = document.body.innerHTML + "1";
立即運行並返回myAsyncFunc
(基本上返回Promise
)。
500 毫秒后, setTimeout
執行,因此document.body.innerHTML = document.body.innerHTML + "2"
運行。 之后,下一行return resolve()
返回,這標志着Promise
完成。
一旦返回resolve
, await
就結束了,因此添加了“3”
我認為您可能對async
關鍵字的作用有誤解。 它並沒有神奇地將 function 更改為異步,盡管它的名字。 它只做以下兩件事:
await
。 但只有當這兩者一起使用時,它才真正有用。 一個沒有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.