Sunday, 29 April 2018

Promises and the Event Loop

I've been reading some documents/articles about the JavaScript event loop (particularly for node.js) and I've found the explanation for what I had noticed in this post regarding awaiting an already resolved promise and the "jumping out" of the async function.

This series looks particulary good. The documentation about the event loop tends to be confusing (particularly the node.js documentation, this discussion helps to clarify it a bit though), but this one seems rather clear (hope it's not simplifying things too much and getting things not fully correctly).

The main idea is that the event loop goes through several phases, traversing several queues where different events/handlers/callbacks have been enqueued. There are 2 "intermediate queues" with a sort of high priority, as they are checked several times per iteration (one time after the traversal of any of the other queues). One of these 2 queues is the Micro task queue. This queue is used for Promises, well, for Promises callbacks, I mean, the handlers attacched to a Promise via then or catch. These callbacks/handlers are added to that queue when the corresponding Promise is resolved. If you add the handlers to an already resolved Promise, the handlers are added to the queue. So contrary to Tasks in .NET, the callback is not executed immediately, but added to the queue. This is what explains the behaviour that I mentioned in my previous article. An example (I'm not using await this time, just then().

let p1 = Promise.resolve("hi");
p1.then(it => console.log("the result is: " + it));

console.log("after resolve and then");

p1.then(it => console.log("and again is: " + it));

// after resolve and then
// the result is: hi
// and again is: hi

You can see how the "console.log" is executed before the "then handler" that got added in a previous line to an already resolved Promise. This answer fully matches with my understanding of Promises and the queue.

When a promise fulfills or rejects, the promise library puts tasks onto the queue for all the attached then or catch handlers. (If a then or catch handler is attached after the promise fulfills or rejects, then the task is put on the queue immediately.)

No comments:

Post a Comment