首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >JavaScript中输出UsIng Async-Await的意外顺序,需要解释

JavaScript中输出UsIng Async-Await的意外顺序,需要解释
EN

Stack Overflow用户
提问于 2021-04-23 16:45:00
回答 2查看 48关注 0票数 1

对于以下代码:-

代码语言:javascript
复制
let p1 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log("one");
    resolve("data1");
  }, 8000)
})
let p2 = new Promise((resolve, reject) => {
  setTimeout(() => {
    console.log("two");
    resolve("data2");
  }, 5000)
})

let func1 = async() => {

  await p1;
  console.log("middle");
  await p2;

}

func1();

在我对async-await的理解中,上面代码的输出应该是:

代码语言:javascript
复制
    one  
    middle  
    two

我期望的总运行时间是13秒

我认为这是因为使用await,我们可以按顺序执行promise,并且只有在调用第一个promise(p1)的console.log()之后,控制才应该移动到下一行(即resolve(“中间”))。因此,根据我的说法,代码将以遇到"await p1;“行的方式运行,然后等待8秒以得到解析,然后移动到下一行,依此类推。

但我在控制台中得到的输出是:

代码语言:javascript
复制
    two
    one
    middle

总运行时间约为8秒,而不是预期的13秒。

有人能解释一下我在这里弄错了什么吗?

EN

回答 2

Stack Overflow用户

发布于 2021-04-23 16:47:24

计时器回调不会因为您正在等待一个完全不同的承诺而受到任何阻碍或延迟。

你的困惑可能是思考承诺做某事的常见困惑。:-)它们不会。您传递给new Promise ( promise executor函数)的函数在您调用时同步和立即,而不是稍后使用promise时。它的目的是启动promise将观察/报告完成的异步流程。因此,您的setTimeout调用是立即执行的,一个接一个。由于您在setTimeout回调中执行"one""two" console.log,因此在5秒后看到"two",在3秒后看到"one" (在8秒之后)。

在第二个promise实现之前,您不会看到"middle",因为(我想您知道)您的await会让async函数中的代码等待第一个promise得到解决,然后再继续。但该await对计时器回调何时运行没有任何影响。

票数 3
EN

Stack Overflow用户

发布于 2021-04-23 16:53:44

Promise在实例化后立即运行。因此,在您的示例中,一旦创建了promise,p1p2就会执行。它们都设置了一个特定的超时,通过写入控制台并调用resolve来解析promise。

然后,等待p1解析。从超时开始,预计需要8秒。但是在此之前,p2的超时时间结束了,所以promise的“内部”部分被调用,将two写入控制台并解析p2

一旦经过8秒,p1就会将one写入日志并进行解析。然后,您的代码继续执行,编写middle。由于p2在被调用时已经解析,所以最终的await什么也不做。

为了让代码按您所希望的那样工作,您应该在await p1行之后创建p2,或者,更好的做法是使用.then()链接p1p2,以便p2在解析p1后开始运行。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67226780

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档