整天困扰着我的javascript承诺问题

整天困扰着我的javascript承诺问题,javascript,promise,Javascript,Promise,这段代码是如何工作的 新承诺(解决=>{ 新承诺(resolve1=>{ 控制台日志(1) resolve1() }) .然后(()=>{ 控制台日志(2) }) .然后(()=>{ 控制台日志(3) }) 解决() }) .然后(()=>{ 控制台日志(4) }) //定义新承诺1 新承诺(解决=>{ //定义新承诺2 新承诺(resolve1=>{ //打印1 控制台日志(1) //解决承诺1 resolve1() }) .然后(()=>{ //解决1(然后是方法)后,打印2 控制台日志(

这段代码是如何工作的

新承诺(解决=>{
新承诺(resolve1=>{
控制台日志(1)
resolve1()
})
.然后(()=>{
控制台日志(2)
})
.然后(()=>{
控制台日志(3)
})
解决()
})
.然后(()=>{
控制台日志(4)
})
//定义新承诺1
新承诺(解决=>{
//定义新承诺2
新承诺(resolve1=>{
//打印1
控制台日志(1)
//解决承诺1
resolve1()
})
.然后(()=>{
//解决1(然后是方法)后,打印2
控制台日志(2)
})
.然后(()=>{
//这里我们看到then方法链,所以在then 1之后
//打印3.但请记住,我们也会解决
//承诺1在承诺2实际发生之前,
//现在JS正在做自己的“并行”任务
//(任务/微任务池,事件循环)
控制台日志(3)
})
//解决承诺1
//在此之前,承诺2已完成
解决()
})
.然后(()=>{
//然后此方法打印4
控制台日志(4)
})
每当调用“resolve()”完成承诺时

另外,JavaScript函数调用不会阻塞,这意味着当您执行时。然后对某个对象执行,然后再执行另一个调用,将首先执行第二个调用,然后执行第一个调用。与setTimeout等类似

这里

首先声明一个新的Promise,它本质上不记录任何东西(1除外)’该Promise的记录只发生在中。然后调用,如前所述,在随后的(一些)常规函数调用之后执行 然后,您将使用主分辨率跟踪它,它将打印4。同时,console.log需要时间来运行,因此即使控制台记录了2,但它在打印4之前没有足够的时间记录3,4不依赖于等待承诺链


问题?

最容易理解承诺会发生什么,就是尽可能地解除承诺

所以在这种情况下,我们必须记住,
Promise
构造函数是同步运行的,微任务被推送到队列(FIFO),只有当我们用
附加回调的Promise解析时,我们的回调才会被推送到该队列

所以我们可以像这样重写您的代码片段:

const-outer\u 1=新承诺(解析=>{
const internal_1=新承诺(resolve1=>{
控制台日志(1);
resolve1();
});
const inner_2=inner_1。然后(()=>{
控制台日志(2);
});
const inner_3=inner_2。然后(()=>{
控制台日志(3);
})
解决()
});
const outer_2=outer_1。然后(()=>{
控制台日志(4)
})
/*
以及执行令:
#同步
内部_1->
日志(1)
队列微任务(inner2)
外部_1->
队列微任务(outer2)
#微任务检查点
内部_2->
日志(2)
队列微任务(inner3)
外部_2->
日志(4)
内部_3->
日志(3)

*/
它们是两个独立的承诺,无论您以何种顺序做出承诺,它们都将并行执行。如果您希望获得1、2、3、4的订单,您必须正确地将它们链接起来,或者使用
承诺将它们组合在一起

让外部承诺,内部承诺;
outerPromise=新承诺(解决=>{
innerPromise=新承诺(resolve1=>{
控制台日志(1)
resolve1()
})
.然后(()=>{
控制台日志(2)
})
.然后(()=>{
控制台日志(3)
})
解决()
})
.然后(()=>{
所有([outerPromise,innerPromise]),然后(()=>console.log(4));

});
因为您在第三个
之前调用了
resolve()
。然后可以调用()

它是这样执行的

new Promise(resolve => {
    new Promise(resolve1 => { // okay. we're not waiting. let's keep moving
        console.log(1)
        resolve1(); // oh, yay! let's call .then()
      })
      .then(() => {
        console.log(2) // nothing was returned! let's call .then()
      })
      .then(() => {
        console.log(3) // nothing was returned! let's call .then()
      });
    // this is the next thing to be called after new Promise(resolve1 ...)
    // it will be called almost at the exact same time that resolve1() is called
    resolve(); oh, yay! let's call .then()
  })
  .then(() => {
    console.log(4)
  })

首先,执行顶层代码:

通过执行,两个函数被添加到微任务队列(红点)。然后,执行微任务队列:

向微任务队列中添加一个函数,然后执行微任务队列中的函数:


结束。

有什么特别困扰你的?你在挣扎什么?“这个代码是如何工作的?”-它没有。(你的意思似乎是“它为什么打印1、2、3、4?”,但它没有这样做。)看看承诺和微任务——我认为这是获得理解的最佳方式;)@杰西卡,因为它应该打印1234。或者,如果主要解决方案不在其他承诺的顺序中,那么为什么它在4之前打印2,它应该是1423或4123或1234,为什么它是串联的,但不是完全的(1243表示主要解析发生在另外两次
调用之间,为什么应该在这两次调用之间,而不是在每次调用之后或之前?@yuqing zhang查看我的评论更新,我在第一次调用中没有看到它。)time@tarkh您所说的“/”仍然不正确,这里我们看到then方法链,因此在then之后1//print 3”这不是发生的事情,在1之后,4被打印出来,然后是3,这是问题的主要点,为什么最后的书面决议应该发生在两个thens之间
new Promise(resolve => {
    new Promise(resolve1 => { // okay. we're not waiting. let's keep moving
        console.log(1)
        resolve1(); // oh, yay! let's call .then()
      })
      .then(() => {
        console.log(2) // nothing was returned! let's call .then()
      })
      .then(() => {
        console.log(3) // nothing was returned! let's call .then()
      });
    // this is the next thing to be called after new Promise(resolve1 ...)
    // it will be called almost at the exact same time that resolve1() is called
    resolve(); oh, yay! let's call .then()
  })
  .then(() => {
    console.log(4)
  })