0

I've the below piece of code and want to understand how event loop, macro-task queue and micro-task queue come into picture.

I've recently started learning about the above concepts so let me me know if I understand things correctly.

  1. Whenever setTimeout(callback, time) is called, the JS engine lets the WebAPI handle the execution of setTimeout. The WebAPI executes the setTimeout by waiting for time interval and followed by immediately putting the callback function in to the macro-task queue. Could anyone tell what all does - setTimeout(callback, time).then(anotherCallback) do in terms of pushing callback and anotherCallback into the different queues?

  2. The code inside a Promise runs synchronously in nature but whenever that promise gets resolved, the callback function attached to it gets pushed to the micro-task queue. The microtask queue has higher priority as compared to the macrotask queue.

Coming to the below code:

Promise.resolve()
  .then(() => {
    setTimeout(() => alert("timeout"), 0);
  })
  .then(() => {
    alert("promise");
  });

Promise resolves immediately, and the callback should be put into microtask queue so,

  setTimeout(() => alert("timeout"), 0);

is put into the microtask queue. The event loop should put the above setTimeout into the callback queue for execution whenever the call stack becomes empty. The JS engine sees that setTimeout is an asynchronous function so it gives it to the WebAPI which handles its execution. The WebAPI waits for 0 seconds and puts the alert("timeout") callback into the macrotask queue. This alert("timeout") callback should be picked and put into the callback queue and alert "timeout" message should be generated.

I didn't quite get when does the last .then executes which alerts the "promise" message on screen? I'm pretty sure that it's due to the promise returned by the setTimeout and unsure on when does it executes.

Ajay Negi
  • 71
  • 11
  • 5
    `setTimeout(callback, time).then(anotherCallback)` is wrong. `setTimeout()` doesn't return a promise, it returns the timer ID (an integer), so you can't call `.then()` on it. – Barmar Jul 10 '23 at 20:50
  • 3
    Your code is doing `.then(() => { setTimeout(…); return undefined; }).then(() => { alert("promise"); })`. The promise chaining completely ignores the `setTimeout`, it just resolves the middle promise with `undefined` and immediately schedules the next fulfillment handler. – Bergi Jul 10 '23 at 21:11
  • @Bergi 1. The second callback function should only be pushed into the micro-task queue after - "the first callback has been resolved, put into the microtask queue, taken out of the microtask queue, put into the call stack and executed on the call stack"? 2. Also, a generic question - for a callback function to get resolved, do all of the asynchronous code inside it has to get completely executed or the execution should reach till the end of the callback function? – Ajay Negi Jul 11 '23 at 07:00
  • I do not know what you mean by "*a callback function to get resolved*", where did you get that terminology from? Promises get resolved, callbacks get registered/scheduled/executed/called. – Bergi Jul 11 '23 at 11:43
  • Yes, the second `then` callback only gets put into microtask queue after the promise has been resolved with the return value of the first `then` callback. – Bergi Jul 11 '23 at 11:45
  • @Bergi Sorry, I meant - _the_ _promise_ _to_ _get_ _resolved_. ie - I think the 3rd point in [here](https://stackoverflow.com/a/31453579) is incorrect which says- `The success or the error handler in the then function will be called only once, after the asynchronous task finishes.` Instead, The success/error handler will be called after the promise resolves/rejects. It doesn't mean that the asynchronous code inside promise has to be completely finish execution. Am I right? – Ajay Negi Jul 13 '23 at 07:11
  • 1
    @AjayNegi It is generally assumed that the promise produced for the result of the asynchronous task is fulfilled or rejected by the asynchronous task when it finishes - everything else (i.e. the task continuing to do something after resolving the promise) would be unconventional and probably a bad practice. So you're right, it's not impossible, but with the common definition of "task" their point is not wrong either. – Bergi Jul 13 '23 at 13:47

0 Answers0