繁体   English   中英

在执行之前,JavaScript 中的异步承诺存储在哪里?

[英]Where are asynchronous promises stored in JavaScript before execution?

我已经使用 JavaScript 几年了,最近对高级 JavaScript 概念进行了大量研究。 我了解到函数回调存储在通常称为事件队列或消息队列的队列中,这就是允许 JavaScript 异步操作的原因。

我从许多来源了解到,在事件队列上的回调之前执行承诺。 我的个人实验也证实了这种行为。 然而,两者似乎都被推到了同一个队列中。 如果承诺与其他所有回调共享相同的队列,那么它们如何首先执行?

从逻辑上讲,我认为承诺会被推送到具有比事件队列中的回调更高的优先级的不同队列,但我找不到任何来源来支持这一点。

我知道所有浏览器对事件队列的处理方式不同,不同的环境会观察到不同的行为。 但是,我一定错过了一些东西。

这是实现定义的。 ECMAScript (JavaScript) 规范只要求在同步 JavaScript 代码之后按顺序执行then回调(和等待)的作业( EnqueueJob )。

在它之外发生的一切(在 Node 或浏览器 DOM API 中带有 I/O 回调的“事件循环”)都由平台控制。

即: - Promise 回调调度是 JavaScript 和 ECMAScript 规范的一部分。 - 其他 I/O(例如计时器、文件访问、DOM 用户交互事件、网络访问)由主机平台而非 JavaScript 决定。 这可以是 Node.js 或浏览器 DOM API。

无论是一个队列还是两个队列都是实现定义的。

我将选择一种实现(Node.js)。 在 Node.js(和 Chrome)中,它们存储在两个不同的队列中。

Promise 回调通过 V8 的 Isolate(执行环境)的RunMicrotasks方法“运行”。 这发生在next_tick.js

function runNextTicks() {
  if (tickInfo[kHasScheduled] === 0 && tickInfo[kHasPromiseRejections] === 0)
    runMicrotasks();
  if (tickInfo[kHasScheduled] === 0 && tickInfo[kHasPromiseRejections] === 0)
    return;

  internalTickCallback();
}

这会调用 V8 的微任务队列。 另一方面,回调通过 node.cc 中的libuv运行。

有两个队列(libuv 和 V8),V8(微任务队列)有机会在 libuv 的每两个项目之间运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM