Home > Enterprise >  does Javascript .then() function check for the promise in a web api
does Javascript .then() function check for the promise in a web api

Time:05-30

Thank you for reading this.

I'm really struggling with fully understanding how async programming works in Javascript. Imagine this code:

Promise.resolve().then(randomcallback)

So in this scenario what I think would happen is the following: Firstly, in the normal call stack the Promise.resolve() function would immediately resolve a Promise object and return it. Then, the .then() function checks if the promise is resolved and if so it adds the randomcallback function to the microtask queue which when the call stack is empty gets executed and returns a new promise object. But imagine if instead of calling the .then() function on a resolved promise object, we call it on a pending object. How is the then function able to check when the Promise object is resolved? Is it constantly checking in some web api thread like some event listener (since the rest of the program can run on) for the status property to be changed to fulfilled to then pass the callback function to the microtask queue?

The same for async await, does the await keyword just contact some web api to listen when the promise gets resolved? If so does it still do that if the promise object is already resolved at the beginning (no settimeout in it) if you use:

randomunresolvedpromise.then(randomcallback)

let's say that randomunresolvedpromise gets fulfilled in 3 seconds (when callstack is empty) how is the .then function even executed (also I've looked at the source code of the library, but it's really confusing since it uses so many callback functions) since the program literally keeps running and randomresolvedpromise only gets fulfilled when the stack is empty, is the function also just waiting in some sort of web api or what?

I've literally watched a lot of videos, read a lot of articles, but they don't seem to touch what really goes on in the event loop when using Promises and async and await. It's all really confusing to me, I hope my question really makes any sense. I really appreciate any answer, thanks!

CodePudding user response:

How is the then function able to check when the Promise object is resolved?

It doesn't. The then method puts the callback on the promise's list of fulfillment callbacks, and then its job is complete. Later, when the promise is fulfilled, it's that code (fulfilling the promise) that puts calls to the promise's fulfillment callbacks in the microtask queue. (You're right though that it's then that does it when the promise is already fulfilled when then is called.)

await works the same way, since await is "just" syntactic sugar for then. (That "just" skips over a lot of details, though. :-D )


Side note: You'll notice I said "fulfillment callbacks," not "resolution callbacks," and referred to the promise being fulfilled (not resolved). There's a big difference between "fulfilled" and "resolved," but unfortunately it's not well understood and people use "resolve" where they mean "fulfill" a lot. See my blog post here (which the MDN folks linked from their documentation) for the difference (and why it matters). (That said, if you say you "resolve the promise with X" and X isn't a promise or other thenable, that's basically synonymous with "fulfill the promise with X." That's not true when X is a promise or other thenable.)

CodePudding user response:

Consider the following code example:

promise1
  .then(() => console.log("foo")
  .then(() => console.log("bar"))

In the above code example, we have 3 promise: promise1, promise1.then(), and promise1.then().then(). (Let's name them p1, p2, and p3 respectively).

Let's assume that p1 takes 3 seconds to fulfil. Upon the execution of the above code, both then methods will be called one after the other, adding their callbacks to the internal list containing the fulfilment callbacks of the promise on which then() method is called.

So, p1.then() will add () => console.log("foo") in the internal fulfilment callbacks list of p1. Similarly, p1.then().then() will add () => console.log("bar") to the internal list of fulfilment callbacks of p2.

Remember all of this happens before p1 fulfils which we have assumed to take 3 seconds. At this point, all the promises: p1, p2, and p3 are in pending state.

p1 --> pending
p2 --> pending
p3 --> pending

Once p1 fulfils, a job will be queued in the micro-task queue to execute the callback passed to p1.then(). At this point, we have:

p1 --> settled (fulfilled)
p2 --> pending
p3 --> pending

(promise is said to have settled when it has either fulfilled or rejected)

After the execute of the callback passed to the p1.then(), promise returned by p1.then(), i.e. p2 fulfils; as a result, another job is enqueued in the micro-task queue to execute the callback passed to p1.then().then().

Now we have:

p1 --> settled (fulfilled)
p2 --> settled (fulfilled)
p3 --> pending

Now, as with p2, p3 will be fulfilled after the execution of the callback passed to p1.then().then() but there are no fulfilment handlers for p3. As a result, no job will be enqueued as there is nothing to do in response to the fulfilment of p3.

p1 --> settled (fulfilled)
p2 --> settled (fulfilled)
p3 --> settled (fulfilled)
  • Related