我正在学习awaitasync关键字.我的书上说下面的代码从1到9输出,而不是Firefox和Chrome的输出。1 2 3 4 5 8 9 6 7
我同意与浏览器.我的书把重音关于不同的行为,当 await
是从承诺开始的,即 await Promise.resolve(1)
将不同于 await 1
在处理程序放在队列中的方式中,它讲的是不同的队列。这是一个书本上的错误吗?await 6
遇到 6
转换为 Promise(6)
那么 Promise(6).then(handler)
发生在幕后,同步模式的执行被打断,Promise已经解析,因此处理程序被放入Job Queue中。控制权传递给调用函数,该函数继续运行剩余的同步外部代码。之后,Job Queue中的处理程序被执行,它执行剩余的代码在 bar function
从而以异步的方式。await 6
将返回6。
当我执行 Promise.resolve(8)
同样的事情也会发生,8号会比6号更早被打印出来,因为 foo function
被首先调用,因此处理程序被放在了工作队列的第一位。
我是否遗漏了什么,这是一个书本上的错误,或者同时改变了一些东西,或者这个特定的行为是与浏览器无关的,因为它没有在ecmascript规范中指定?此外,我想知道,如果在事件循环消息队列Job Queue机制中引入asyncawait(),是否改变了一些东西。
async function foo(){
console.log(2);
console.log(await Promise.resolve(8));
console.log(9);
}
async function bar(){
console.log(4);
console.log(await 6);
console.log(7);
}
console.log(1);
foo();
console.log(3);
bar();
console.log(5);
下面是本书的页面及相关代码和说明。第1页
书的作者在这里!
当写这一章的时候,我是在Firefox v64(以及它们的当代厂商版本)上测试的。如果你安装了这个 浏览器版本,你会发现这个例子可以正常工作。
我将中断的版本缩小到Firefox 69,它是在本章编写和编辑团队测试后几个月发布的。你会注意到,在 发行说明在 "API "一节中,有一个公告 "微任务API(Window或WorkerGlobalScope.queueMicrotask())已经实现"。
在 "API "部分,有一栏 "微任务API(Window或WorkerGlobalScope.queueMicrotask())已经实现"。HTML规范中的相关部分 的内容如下。
...关于queueMicrotask()的最佳思考方式是作为一种重新安排同步代码的机制,有效地将排队的代码紧跟在当前任务的非排队JavaScript之后。
现代浏览器中的诺言实现利用了微任务API,它改变了这个例子的执行顺序。具体来说,书中的例子利用了 await Promise.resolve(8)会有效地延迟这个日志语句两个周期的行为--一次是 await,一次是 Promise.resolve()。现在promise使用微任务队列,不再是这种情况,因此书中的日志输出是不正确的。
这个错误的报告是 今年年初 并被从书中删除。
是的,是的 await 6
是 await Promise.resolve(6)
解释如下 此处.
所以你的代码就变成了。
async function foo(){
console.log(2);
console.log(await Promise.resolve(8));
console.log(9);
}
async function bar(){
console.log(4);
console.log(await Promise.resolve(6));
console.log(7);
}
console.log(1);
foo();
console.log(3);
bar();
console.log(5);
没有理由在第一个等待之前发生第二个等待。自然,8会在6之前被解决。因此,是的,这本书是错误的。
然而,如果8的承诺做了一些实际的等待,它将是正确的。例如
async function foo(){
console.log(2);
console.log(await new Promise(resolve => setTimeout(() => resolve(8), 100)));
console.log(9);
}
async function bar(){
console.log(4);
console.log(await Promise.resolve(6));
console.log(7);
}
console.log(1);
foo();
console.log(3);
bar();
console.log(5);
这确实是书上说的输出结果。
1
2
3
4
5
6
7
8
9
作者要么假设这其中一个会比另一个花更多的时间, 要么就是他碰巧使用了一个奇怪的js引擎, 谁知道呢.