javascript 为什么Promises的结果看起来不正确?

csbfibhn  于 2023-05-27  发布在  Java
关注(0)|答案(2)|浏览(100)
Promise.resolve(1)
    .then(x => console.log(1))
    .catch(x => console.log(2))
    .then(x => console.log(3))

Promise.reject(2)
    .then(x => console.log(4))
    .catch(x => console.log(6))
    .then(x => console.log(7))

结果是“1 6 3 7”,但如果我在catch之前添加另一个then()console.log(6),结果将是1 3 6 7,我不明白为什么

Promise.resolve(1)
    .then(x => console.log(1))
    .catch(x => console.log(2))
    .then(x => console.log(3))

Promise.reject(2)
    .then(x => console.log(4))
    .then(x => console.log(5))
    .catch(x => console.log(6))
    .then(x => console.log(7))

结果为1 3 6 7
我想知道它是怎么运作的

rqenqsqc

rqenqsqc1#

Promise侦听器由Promise任务运行器作业在Promise已实现或被拒绝时运行。HTML 5使用微任务队列作为Promise Job队列,队列作为FIFO(先进先出)运行。
在其他JavaScript返回到事件循环之后,Promise Job连续运行,直到Promise Job队列为空。
promise作业的目的是将创建作业的promise的值或拒绝原因传递到promise链中的下一个promise。
如果生成作业的promise被满足,下一个promise将以相同的值被满足,如果被拒绝,则以相同的原因被拒绝。如果一个promise监听器返回一个promise,那么下一个promise将使用返回的promise进行解析。
将promise状态和值传递给下一个promise是使用内部存储的resolvereject函数的¹值来执行的。
值得注意的是,catch子句是then的两个参数调用的简写²。无论源代码中的子句是then还是catch,都仍然会创建promise作业来解析、实现或拒绝子句返回的promise对象。
将所有这些放在一起,应该可以预测在同时处理多个promise链的情况下promise侦听器执行的顺序。
第一个示例按以下顺序将promise作业相互啮合:

  1. log(1),而不是log(4)
    1.不是log(2),而是log 6
  2. log(3),log(7)
    第二个示例也使程序作业相互啮合,但具有不同的对齐:
  3. log(1),而不是log(4)
    1.非log(2),非log(5)
  4. log(3),log(6)
    1.日志(7)
    故事的寓意?不要依赖于promise队列中多个作业的执行顺序,如果需要部分完成结果,可以将promise链分成更小的链。
    ¹关于链式promise的resolvereject函数。
  • Promise对象内部存储resolvereject函数,用于调用thencatchfinally方法返回的Promise。
  • Promise作业使用这些存储的函数来解析、履行或拒绝链中的下一个Promise。
  • 所存储的函数在内部引用它们被发出的承诺。通常,这就是在内存中保存链式promise并防止它们在结算之前被垃圾收集的原因。

²关于带一个参数的then调用

  • then(listenerFunction)相当于then(listenerFunction, null)。如果将null作为rejection handler应用于一个被拒绝的promise,则会导致链中的下一个promise以相同的原因被拒绝。
  • catch(listenerFunction)相当于then(null, listenerFunction)。应用于一个已实现的promise,null作为fulfillment处理程序会导致链中的下一个promise以相同的值实现。

不适用于链中前一个promise的稳定状态的Promise链子句跳过-它们主动将前一个promise的状态和值传递到为此目的而进入微任务队列的promise作业中的下一个promise。

qvtsj1bj

qvtsj1bj2#

您第一次调用了Promise.resolve,因此将调用then回调。任何后续的then回调也将被调用。
接下来,您调用了Promise.reject,这意味着每个then回调都将被忽略,直到catch回调(拒绝处理程序)。但是,一旦catch处理程序完成解析(或完成返回某些内容),如果它没有抛出错误,则会调用下一个then回调。

相关问题