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 位)
这个和入栈顺序有关系。你可以在VSC里面用调试模式看到这个具体函数执行和微任务入栈过程。
Promise.prototype.finally()
方法返回一个 Promise,并且在 promise 执行结束时,无论其状态如何,都会执行指定的回调函数。这个方法的回调函数会在当前 Promise 链的最后执行,但它不会改变 Promise 的结果或者状态。
在你提供的代码中,finally
是在 a().then(...)
链的末尾被调用的,但是它不会阻塞或改变 a().then(...)
链的异步执行流程。finally
仅仅确保,无论 a().then(...)
的结果如何,它内部的回调最终都会被调用,但是它并不改变链中其他 then
的执行顺序。
b()
函数返回一个新的 Promise,这个 Promise 在 a()
完成并解析其值后解析为 2
。a()
中的 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