简体   繁体   English

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

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

I've been using JavaScript for a few years now and have recently done a lot of research on high level JavaScript concepts.我已经使用 JavaScript 几年了,最近对高级 JavaScript 概念进行了大量研究。 I have learned that function callbacks are stored on a queue usually referred to as the event queue or message queue, and that this is what allows JavaScript to operate asynchronously.我了解到函数回调存储在通常称为事件队列或消息队列的队列中,这就是允许 JavaScript 异步操作的原因。

I've learned from many sources that promises are executed before callbacks on the event queue.我从许多来源了解到,在事件队列上的回调之前执行承诺。 My personal experiments also confirm this behavior.我的个人实验也证实了这种行为。 However both seemed to get pushed to the same queue.然而,两者似乎都被推到了同一个队列中。 How are promises executed first if they share the same queue as every other callback?如果承诺与其他所有回调共享相同的队列,那么它们如何首先执行?

Logically I'd assume promises get pushed onto a different queue with a higher priority than callbacks in the event queue, but I can't find any sources to back this.从逻辑上讲,我认为承诺会被推送到具有比事件队列中的回调更高的优先级的不同队列,但我找不到任何来源来支持这一点。

I understand that all browsers handle the event queue differently, and that different behaviors will be observed by different environments.我知道所有浏览器对事件队列的处理方式不同,不同的环境会观察到不同的行为。 However I must be missing something.但是,我一定错过了一些东西。

This is implementation defined.这是实现定义的。 The ECMAScript (JavaScript) specification only requires that jobs ( EnqueueJob s) for then callbacks (and awaits) are executed after synchronous JavaScript code and in order. ECMAScript (JavaScript) 规范只要求在同步 JavaScript 代码之后按顺序执行then回调(和等待)的作业( EnqueueJob )。

Everything that happens outside of it ("the event loop" with I/O callbacks in Node or the browser DOM APIs) are controlled by the platform.在它之外发生的一切(在 Node 或浏览器 DOM API 中带有 I/O 回调的“事件循环”)都由平台控制。

That is: - Promise callback scheduling is a part of JavaScript and the ECMAScript specification.即: - Promise 回调调度是 JavaScript 和 ECMAScript 规范的一部分。 - Other I/O (such as timers, file access, DOM user interaction events, network access) is determined by the host platform and not JavaScript. - 其他 I/O(例如计时器、文件访问、DOM 用户交互事件、网络访问)由主机平台而非 JavaScript 决定。 This can be Node.js or the browser DOM API.这可以是 Node.js 或浏览器 DOM API。

Whether it's one or two queues is implementation defined.无论是一个队列还是两个队列都是实现定义的。

I'm going to pick one implementation (Node.js).我将选择一种实现(Node.js)。 In Node.js (and Chrome) they're stored in two different queues.在 Node.js(和 Chrome)中,它们存储在两个不同的队列中。

Promise callbacks are "run" through the RunMicrotasks method of V8's Isolate (execution environment). Promise 回调通过 V8 的 Isolate(执行环境)的RunMicrotasks方法“运行”。 This happens in next_tick.js :这发生在next_tick.js

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

  internalTickCallback();
}

This calls into V8's microtask queue.这会调用 V8 的微任务队列。 On the other hand callbacks are run through libuv in node.cc .另一方面,回调通过 node.cc 中的libuv运行。

There are two queues (libuv's and V8's) and V8's (the microtask queue) gets a chance to run between every two items in libuv's.有两个队列(libuv 和 V8),V8(微任务队列)有机会在 libuv 的每两个项目之间运行。

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

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