As others have mentioned in the comments under the question, you shouldn't rely on the timing or order in which unrelated promises are resolved.
Having said that, there is an explanation of the output your code produces.
Callbacks passed to then()
and catch()
methods are invoked asynchronously and are enqueued in a micro-task queue.
Calling Promise.resolve(1)
creates a resolved promise; as a result, the callback passed to Promise.resolve(1).then(...)
is put in a micro-task queue.
[
(x) => console.log(1)
]
After this, Promise.reject(1)
is called which creates a rejected promise. This will reject the promise returned by Promise.reject(1).then(...)
.
[
reject(Promise.reject(1).then(...)),
(x) => console.log(1)
]
End of execution of your script
Event loop will start processing the micro-task queue which has two tasks in it
[
reject(Promise.reject(1).then(...)),
(x) => console.log(1)
]
1
is logged on the console. After logging 1
, promise returned by Promise.resolve(1).then(...)
is fulfilled with the value of undefined
.
This will lead to the fulfilment of the promise returned by Promise.resolve(1).then(...).catch(...)
[
resolve(Promise.resolve(1).then(...).catch(...))
reject(Promise.reject(1).then(...))
]
Next task in the queue is to reject the promise returned by Promise.reject(1).then(...)
. This rejection of promise queues another micro-task
queue: [
x => console.log(6),
resolve(Promise.resolve(1).then(...).catch(...))
]
console output: 1
Promise returned by Promise.resolve(1).then(...).catch(...)
is resolved which queues x => console.log(3)
in the micro-task queue
queue: [
x => console.log(3),
x => console.log(6)
]
console output: 1
"6" is logged on the console
queue: [
x => console.log(3),
]
console output: 1 6
After logging 6
, promise returned by the catch
method if fulfilled with the value of undefined which queues another micro-task
queue: [
x => console.log(7),
x => console.log(3)
]
console output: 1 6
3
is logged on the console
queue: [
x => console.log(7),
]
console output: 1 6 3
7
is logged on the console
queue: []
console output: 1 6 3 7
If add .then(x => console.log(5)), then result is equal 1 3 6 7.
With an extra then()
method call, it takes an extra step in the micro-task processing cycle to queue
x => console.log(6)
in the micro-task queue which results in
x => console.log(3)
getting processed before x => console.log(6)
.