当从Promise rathen后面跟着一个数字的时候,waiting的行为应该是不同的吗?

问题描述 投票:0回答:1

我正在学习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页

第2页

javascript async-await es6-promise ecmascript-7
1个回答
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使用微任务队列,不再是这种情况,因此书中的日志输出是不正确的。

这个错误的报告是 今年年初 并被从书中删除。


2
投票

是的,是的 await 6await 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引擎, 谁知道呢.

© www.soinside.com 2019 - 2024. All rights reserved.