3

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.

  • See [Understanding the Event Loop](https://stackoverflow.com/questions/21607692/understanding-the-event-loop) – Phil May 27 '20 at 05:18
  • For a promise that is returned from a native call, yes, this is a fine mental model. In practice, as @kaiido shows below, events that resolve promises are typically schedule as macro tasks. It should hardly make a difference to the execution. – Bergi May 27 '20 at 08:47
  • "*Is it "watching" for changes in the object?*" - no. The value of a promise is not just a object property that is changed by an assignment, it is an internal property and needs to be set using a setter (like `resolve()` and `reject()`). It is this setter that does enqueue the reaction jobs. – Bergi May 27 '20 at 08:50
  • Not sure I understand "program still running". What does it mean? – Roamer-1888 May 28 '20 at 00:56

1 Answers1

3

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

Kaiido
  • 123,334
  • 13
  • 219
  • 285