简体   繁体   中英

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. 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.

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.

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.

That is: - Promise callback scheduling is a part of JavaScript and the ECMAScript specification. - Other I/O (such as timers, file access, DOM user interaction events, network access) is determined by the host platform and not JavaScript. This can be Node.js or the browser DOM API.

Whether it's one or two queues is implementation defined.

I'm going to pick one implementation (Node.js). In Node.js (and Chrome) they're stored in two different queues.

Promise callbacks are "run" through the RunMicrotasks method of V8's Isolate (execution environment). This happens in 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. On the other hand callbacks are run through libuv in node.cc .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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