为什么这个异步函数会在它之前定义的等价 Promise.then 链之前执行? [英] Why does this async function execute before the equivalent Promise.then chain defined before it?

查看:27
本文介绍了为什么这个异步函数会在它之前定义的等价 Promise.then 链之前执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下代码:

var incr = num => new Promise(resolve => {
  resolve(num + 1);
});

var x = incr(3)
  .then(resp => incr(resp))
  .then(resp => console.log(resp));

async function incrTwice(num) {
  const first = await incr(num);
  const twice = await incr(first);
  console.log(twice);
}

incrTwice(6);

我认为(可能是错误的)展示了实现相同功能的两种等效方法:第一种是通过链接 promise,第二种是使用 async/await 的语法糖.

Which I believe (perhaps mistakenly) shows two equivalent ways to achieve the same functionality: first by chaining promises and second with the syntactic sugar of async/await.

我希望promise链接解决方案首先打印到console.log,然后是异步函数,但是异步函数console.log的第一个然后promise链接解决方案打印.

I would expect the promise chaining solution to console.log first, then the async function second, however the async function console.log's first then the promise chaining solution prints.

我的逻辑如下:

  1. x 的初始解析将在处理声明时首先出现在微任务队列中
  2. xincrTwice 的声明之间的堆栈是空的,这会导致微任务队列被刷新(导致承诺链的完成)
    • x 先打印
  1. xs initial resolve would be first on the microtask queue as the declaration is processed
  2. the stack is empty between the declaration of x and incrTwice which would cause the microtask queue to be flushed (resulting in the completion of the promise chain)
    • x prints first
  • incrTwice 打印秒

显然我在某处有误解,有人能指出我错在哪里吗?

Clearly I have a misunderstanding somewhere, is someone able to point out where I am wrong?

推荐答案

首先,我要指出,你永远不应该争论独立 promise 链的执行顺序.有两个异步调用,它们不相互依赖而是并发运行,因此应该总是期望它们以任意顺序完成.

First of all, let me point out that you never should argue about the execution order of independent promise chains. There are two asynchronous calls, and they do not depend on each other but run concurrently, so they should always be expected to finish in arbitrary order.

仅使用立即解决承诺的玩具示例使此顺序依赖于微任务队列语义而不是实际的异步任务,这使得这成为纯粹的学术练习(其 结果可能会在规范中发生变化).

Toy examples that only use immediately-resolving promises make this order depend on microtask queueing semantics instead of actual asynchronous tasks, which makes this a purely academic exercise (whose result is subject to changes in the spec).

无论如何,让我们消除你的误解:

Anyway, let's clear up your misunderstandings:

xincrTwice 声明之间的栈是空的,这会导致微任务队列被刷新

the stack is empty between the declaration of x and incrTwice which would cause the microtask queue to be flushed

不,只有在所有用户代码运行完成后,堆栈才会变空.堆栈上仍然有

登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆