Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

The javascript Promise problem that has bothered me all day [duplicate]

How does this code work?

new Promise(resolve => {
    new Promise(resolve1 => {
        console.log(1)
        resolve1()
      })
      .then(() => {
        console.log(2)
      })
      .then(() => {
        console.log(3)
      })
    resolve()
  })
  .then(() => {
    console.log(4)
  })

The result is ‘1 2 4 3’

like image 756
yuqing-zhang Avatar asked Aug 21 '20 09:08

yuqing-zhang


People also ask

What happens if you don't resolve a promise Javascript?

A promise is just an object with properties in Javascript. There's no magic to it. So failing to resolve or reject a promise just fails to ever change the state from "pending" to anything else. This doesn't cause any fundamental problem in Javascript because a promise is just a regular Javascript object.

Can promise resolve multiple times?

No. It is not safe to resolve/reject promise multiple times. It is basically a bug, that is hard to catch, becasue it can be not always reproducible.

How do promises work in Javascript event loop?

During the process of promises microtask queue, one item is again added to the process. nextTick queue ('next tick inside promise resolve handler'). After promises microtask queue is finished, event loop will again detect that there is one item is in the process.

What does a Javascript promise do?

It allows you to associate handlers with an asynchronous action's eventual success value or failure reason. This lets asynchronous methods return values like synchronous methods: instead of immediately returning the final value, the asynchronous method returns a promise to supply the value at some point in the future.


Video Answer


1 Answers

The easiest to understand what happens with Promises is to unchain it as much as you can.

So in this case, we have to remember that the Promise constructor is ran synchronously, microtasks are pushed to a queue (FIFO) and that it's only when the promise to which we attached our callback with .then() will resolve, that our callback will get pushed to that queue.

So we can rewrite your snippet like this:

const outer_1 = new Promise(resolve => {
  const inner_1 = new Promise(resolve1 => {
    console.log(1);
    resolve1();
  });
  const inner_2 = inner_1.then(() => {
    console.log(2);
  });
  const inner_3 = inner_2.then(() => {
    console.log(3);
  })
  resolve()
});
const outer_2 = outer_1.then(() => {
  console.log(4)
})
/*
And the execution order:

# sync
  inner_1 ->
    log(1)
    queue microtask (inner2)
  outer_1 ->
    queue microtask (outer2)
# microtask-checkpoint
  inner_2 -> 
    log(2)
    queue microtask (inner3)
  outer_2 ->
    log(4)
  inner_3 ->
    log(3)
*/
like image 167
Kaiido Avatar answered Sep 29 '22 15:09

Kaiido