-1

In the code snippet below both the setTimeout and reject get executed asynchronous. My impression is that setTimeout pushes to the even queue, then reject pushes to the event queue. Then the setTimeout fetes and executes immediately, the the reject. All that means 6 to be logged first then 3, however o my shock the console logs:

3
6

why is that? Why reject before the setTimeout?

let promise = new Promise(
    function (resolve, reject) {
        setTimeout(() => {
            console.log(" 6 ");
        }, 0);
        reject(" 3 ");
        resolve(" 4 ");
    }
);
promise.then(
    function (st) {
        console.log(st);
    },
    function (st) {
        console.log(st)
    }
);
Waterfr Villa
  • 1,217
  • 1
  • 10
  • 33
  • `setTimeout` will always execute "later" than the current code. So, the operation here is delay a function (logging `6`) -> reject with `3` -> resolve with `4` (but the promise is already rejected) -> /* later */ -> log `6` – VLAZ Nov 27 '20 at 06:51
  • see https://www.youtube.com/watch?v=8aGhZQkoFbQ&ab_channel=JSConf it is explained how js works – deepak thomas Nov 27 '20 at 06:56
  • job que has a higher priority then task que – bill.gates Nov 27 '20 at 07:30

1 Answers1

0

This has to do with the event loop as defined in the Web Spec. The browser has multiple task queues for multiple types of tasks (e.g. timer tasks created through setTimeout), as well as a microtask queue (where Promise settlement gets pushed to). Whenever the browser finishes executing a task, it empties the microtask queue and executes all tasks in it, before continuing with a task from another task queue.

Timeout and Promises both execute code in async way but they have different purpose and charecterstics:

setTimeout delays the execution of a function by specific time duration and does not block the rest of code. Basically setTimeout schedules a macrotask. Promise too does not block rest of the code unless you are using await operator but creates a microtask.

Since microtasks are executed before running the next macrotask, Promise will always be resolved/rejected before setTimeout.

Now in order to get the desired output you need to move the reject() call inside setTimeout

let promise = new Promise(
    function (resolve, reject) {
        setTimeout(() => {
            console.log(" 6 ");
            reject(" 3 ");
            resolve(" 4 ");
        }, 0);
    }
);
abhishek khandait
  • 1,990
  • 2
  • 15
  • 18