当前位置: 首页 > 知识库问答 >
问题:

promise.finally为什么在其调用者的then后面执行?

鲁鹤轩
2024-06-22
const a = () => {  return new Promise((resolve) => {    resolve(1);  });};const b = () => {  return new Promise((resolve) => {    a()      .then((aR) => {        console.log(aR);        resolve(2);      })      .finally(() => {        console.log("A");      });  });};const c = () => {  b().then((bR) => {    console.log(bR);  });};c();

今天有一段代码抽象后逻辑如上述代码,我本来觉得输出顺序应该是

1A2

但实际输出却是

12A

不太理解是为什么,求指教。


环境:Chrome 版本 126.0.6478.115(正式版本) (64 位)

共有2个答案

严繁
2024-06-22

这个和入栈顺序有关系。你可以在VSC里面用调试模式看到这个具体函数执行和微任务入栈过程。

李安歌
2024-06-22

Promise.prototype.finally() 方法返回一个 Promise,并且在 promise 执行结束时,无论其状态如何,都会执行指定的回调函数。这个方法的回调函数会在当前 Promise 链的最后执行,但它不会改变 Promise 的结果或者状态。

在你提供的代码中,finally 是在 a().then(...) 链的末尾被调用的,但是它不会阻塞或改变 a().then(...) 链的异步执行流程。finally 仅仅确保,无论 a().then(...) 的结果如何,它内部的回调最终都会被调用,但是它并不改变链中其他 then 的执行顺序。

b() 函数返回一个新的 Promise,这个 Promise 在 a() 完成并解析其值后解析为 2a() 中的 then 回调首先执行,然后 finally 回调执行。b() 返回的 Promise 在 a()finally 回调执行完毕后解析为 2

c() 调用 b() 并附加一个 then 回调时,这个回调会在 b() 返回的 Promise 解析为 2 时执行。由于 finally 是在 b() 内部的 Promise 链的末尾,所以它的回调会在 b() 返回的 Promise 解析之前执行。

输出顺序为:

1 // a().then((aR) => { console.log(aR); ... } 中的 console.log2 // b().then((bR) => { console.log(bR); } 中的 console.logA // a().finally(() => { console.log("A"); }) 中的 console.log

finally 回调在 a().then(...) 链的末尾执行,但是它不影响 b() 返回的 Promise 的解析顺序。因此,在 c()then 回调中打印 2 的操作会在 finally 回调打印 "A" 之前发生。

简单来说,finally 回调执行的时间点是在当前 Promise 链的末尾,但在返回的 Promise 解析之前。在这个例子中,b() 返回一个 Promise,这个 Promise 在 a()finally 回调执行后解析,所以在 c()then 回调中,2 会先被打印,然后是 a()finally 回调中的 "A"

 类似资料:
  • 问题内容: 该方法: 可以等效地写成: 以我的经验,第二种形式更常见,尤其是在更复杂的方法(可能存在多个此类出口点)中,“掷”和“返回”也是如此。然而,第一种形式可以使代码的条件结构更加明确。有没有什么理由比另一个更喜欢? 问题答案: 以我的经验,这取决于代码。如果我“防备”某些事情,我会这样做: 重点很明确:如果该语句为假,则我不希望该函数继续。 另一方面,有些函数具有多个选项,在这种情况下,我

  • React引入了新的静态方法,它在每个呈现方法之前都会被调用,但为什么呢?在prop change之后调用它对我来说是有意义的,但是在之后调用它就没有意义了,也许我错过了什么。 我根据公司的要求创建了一个组件,在组件中日期是从道具控制的。我在组件中有以下状态。 是的,我在中创建了一个额外的变量来跟踪是否由于而被调用,但我认为这不是正确的方法。 或者是我做错了什么或者遗漏了什么,或者不应该在之后调用

  • 问题内容: 我想知道以下代码的行为背后的机制是什么: 我的理解是不 返回 函数,而是 关闭连接/结束请求 。这可以解释为什么我仍然可以在命令后执行代码(我查看了快速源,但它似乎不是异步函数)。 还有其他我可能会想念的东西吗? 问题答案: 当然可以结束HTTP响应,但是它对您的代码没有做任何特殊的事情。 即使您已结束回复,也可以继续做其他事情。 但是,您 无法 做的是利用进行任何有用的操作。由于响应

  • 问题内容: 我只是想简化我的一个类,并以与flyweight设计模式相同的样式介绍了一些功能。 但是,对于为什么总是调用after ,我有点困惑。我没想到这一点。谁能告诉我为什么会这样,否则我如何实现此功能?(除了将实现放入hack之外)。 这是一个例子: 输出: 为什么? 问题答案: 使用 时,你需要控制一个新实例的创建。 使用 时,你需要一个新的实例的控件初始化。 是实例创建的第一步。首先调用

  • 本文向大家介绍为什么在__new __()之后总是调用__init __()?,包括了为什么在__new __()之后总是调用__init __()?的使用技巧和注意事项,需要的朋友参考一下 Python具有一种称为魔术方法的特殊类型的方法,该方法以前置和双下划线命名。 如果我们想谈论魔术方法__new__,那么显然也需要谈论__init__方法。创建实例时将调用魔术方法__new__。而在创建实

  • 我是JS的新手,正在学习promise。我面临的困惑是,then()中的回调被推送到作业队列中。以下是一个例子: 所以,我们有promise,这是通过console.log('Done')解决的。之后,console.log('Done')被传递给then(),then()中的回调被传递给作业队列。为什么?在从asynchronous setTimeout获得数据之后,为什么需要将callback

  • 我想问为什么接口在 500 之后依然会进行跳转呢?难道不是 catch 然后弹窗报错了么?

  • 据我所知,promise是可以解析()或拒绝()的东西,但我惊讶地发现,promise中的代码在调用解析或拒绝后仍继续执行。 我认为resolve或reject是exit或return的异步友好版本,它将停止所有立即的函数执行。 有人能解释一下为什么下面的示例有时在解析调用后显示console.log的背后思想吗: 杰斯宾