How exactly is a promise's value updated?

Viewed 152

Let's suppose that a fetch request is executed at 2ms. The program keeps running. Then, at 100ms the request has been completed, but the program hasn't finished its execution.

1. At this point, does the browser actually update the value in the Promise object even though the program hasn't finished yet, or does this have to be done in Javascript's thread, when the call stack is empty?

2. How do the onFulfilled and onRejected callbacks get enqueued to the Job queue? As far as I know, they do so when the Promise's state changes, but how exactly is this done? Is the browser behind the scenes "watching" for changes in the object and enqueuing the callback immediately, or is it Javascript that does it when finishing executing synchronous code?

EDIT: I was told in a course that, roughly speaking, what happened under the hood was that the Promise object's property "value" was updated as soon as the request was successfully completed (even if the program was still running), and immediately triggered two things: a change on the Promise's state, and the callback in onFulfillment array to be enqueued in the microtask queue (assuming one was added using then). Is this possible? Does the Promise object actually get modified outside Javascript, or is this done when the program finishes its execution? Please correct me if I make any mistakes.

1 Answers

Assuming that the fetch call will succeed without error, at 100ms when the Request has been correctly sent and the Body is being streamed, a new fetch task is enqueued in the Networking task source which will process the response. This final algorithm is the one responsible to resolve the Promise returned by window.fetch().

So if at 100ms, the browser has something else to do, it will continue to do whatever it was. If when it's done doing that, it feels it has a more important task to do (e.g UI event?), then it will do that before. When it will proceed that fetch task, it will resolve the Promise, and doing so, it will queue a microtask to execute your callback, right after that task is done processing (i.e synchronously here).

Related