繁体   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