[英]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.