Javascript 为什么这个异步函数要在等价的Promise.chain之前执行呢?
我有以下代码:Javascript 为什么这个异步函数要在等价的Promise.chain之前执行呢?,javascript,promise,async-await,es6-promise,Javascript,Promise,Async Await,Es6 Promise,我有以下代码: var incr=num=>新承诺(解析=>{ 解析(num+1); }); 变量x=增量(3) .然后(resp=>incr(resp)) 。然后(resp=>console.log(resp)); 异步函数incrTwice(num){ const first=等待增量(num); 常数两次=等待增量(第一次); console.log(两次); } 增加(6)你的想法是可以理解的,符合逻辑的。观察到的行为的原因与Promise API中内置的保证之一有关,即承诺在执行时始
var incr=num=>新承诺(解析=>{
解析(num+1);
});
变量x=增量(3)
.然后(resp=>incr(resp))
。然后(resp=>console.log(resp));
异步函数incrTwice(num){
const first=等待增量(num);
常数两次=等待增量(第一次);
console.log(两次);
}
增加(6)代码>你的想法是可以理解的,符合逻辑的。观察到的行为的原因与Promise API中内置的保证之一有关,即承诺在执行时始终是异步的,即使它们执行同步操作(如立即解析承诺)。更严格地说,这意味着在当前运行完成之前,永远不会调用承诺的回调
作为MDN:
在JavaScript事件循环结束之前,永远不会调用回调
因此:
我会在我的承诺指南中介绍这一点。首先,让我指出,你永远不应该争论独立承诺链的执行顺序。有两个异步调用,它们互不依赖,而是并发运行,因此应始终期望它们以任意顺序完成
仅使用立即解析承诺的玩具示例使此顺序依赖于微任务队列语义,而不是实际的异步任务,这使得这纯粹是一个学术练习(其在规范中)
无论如何,让我们澄清一下你的误解:
在声明x
和incrTwice
之间,堆栈为空,这将导致刷新微任务队列
否,只有在所有用户代码运行完成后,堆栈才会变为空。堆栈上仍然有
元素的全局执行上下文。在所有同步代码(incr=…
、x=incr(3)…
和incrTwice(6)
)完成之前,不会执行任何微任务
我相信[代码]展示了两种实现相同功能的等效方法:第一种是通过链接承诺,第二种是使用async/await的语法糖
不完全是。当取消测试从第一个然后(…)
处理程序返回的incr(resp)
承诺时,.then()
链接还有一个额外的解析步骤。要使其行为与incrTwice
中的wait
ed承诺完全相同,您需要编写
incr(3).then(resp =>
incr(resp).then(resp =>
console.log(resp)
)
);
如果您这样做,您将按照启动两个承诺链的顺序获得控制台日志,因为在执行控制台.log()
之前,它们将执行相同数量的微任务
有关更多详细信息,请参见,,是,但在我的示例中,两个“版本”都是承诺。我知道承诺将在同一脚本中的任何同步代码之后解析,就像承诺将微任务排队一样,直到堆栈清空后才会刷新。我感兴趣的是微任务队列中两个承诺之间的交错,而不是一个承诺和一段同步代码之间的交错。
incr(3).then(resp =>
incr(resp).then(resp =>
console.log(resp)
)
);