繁体   English   中英

如果then函数未返回承诺,为什么下一个then将立即运行?

[英]If a then function doesn't return a promise, why the next then will be run immediately?

在then()函数内部,如果我没有返回承诺而是直接调用该函数。

doSomething().then(function () {
  doSomethingElse(); //I know I should return doSomethingElse()
}).then(finalHandler);

我知道doSomethingElse & finalHandler将并行运行,而不是顺序运行。 但是我仍然不确定为什么会这样吗?

doSomething
|-----------------|
                  doSomethingElse(undefined)
                  |------------------|
                  finalHandler(undefined)
                  |------------------|

.then()处理程序中运行代码时,将获得以下设计选择:

1.什么也不返回。 这使返回值保持undefined ,这是向父级诺言的信号,即此处没有其他异步操作可以等待,因此诺言链可以继续运行链中的后续步骤。

2.兑现承诺。 这告诉父承诺,您希望将承诺“插入”到链中,并且在解决此承诺之前,不应调用以下.then()处理函数。 连锁店实际上将等待这个承诺。 如果此新承诺最终得以解决,则将调用下一个.then()处理函数。 如果此新承诺最终被拒绝,则将调用下一个.catch()处理函数。

3.引发异常。 这告诉父母承诺,在操作.then()处理程序失败,家长许诺链立即成为拒绝,接下来的.catch()处理程序将被调用。

因此,在您的情况下,如果doSomethingElse()是异步操作,并且没有返回与该异步操作相关的promise,那么您只是将您的promise链“分支”为两个单独的链。 主父链将继续调用下一个.then()处理函数,因为您什么也没有返回。 同时, doSomethingElse()函数本质上是其自己的并行诺言链。 它甚至可以拥有自己的.then()处理程序,如下所示:

 doSomethingElse().then(...).then(...).catch(...)

那只是一个完全独立的承诺链,除了另一个承诺链何时开始的时间之外,它与另一个承诺链根本没有任何联系。 一旦启动,它将独立于其他链条运行。 这在承诺术语中通常称为“分支”。 您进入一个新的链条。 两者相互独立运行。 如果两个分支都使用异步操作(大概是这样做的),则这些异步操作将被交错并同时运行。 他们俩什么时候完成的时间是完全不确定的(因为他们在时间上没有程序关系)。

像这样分支到一个完全独立的promise链通常是一个编程错误,某些promise实现可能会在控制台中报告可能的编程错误。 这通常是错误的原因是,此代码之外的任何人都无法以任何方式监视或捕获分支的独立承诺中的错误。 没有错误处理的承诺是不好的。 他们默默地吃错了。

在某些情况下,如果发生错误,则您合理地不更改程序行为。 通常,当您以较长的顺序结束文件时,甚至只是尝试在发生错误后关闭文件时,您只是想尽最大的努力来关闭文件,而实际上并没有什么用处如果关闭失败(可能记录失败除外),则可以执行此操作,因此没有特殊原因尝试传播回这种类型的失败。 但是,这只能以非常周到的方式进行。 在99.9999%的时间中,错误应传播回调用者并创建一个新的分支且独立的Promise链,因为这样不会将其错误传播回任何地方,因此通常不是正确的编码策略。

该函数不需要返回Promise 如果未明确返回任何内容,则默认返回undefined Javascript中的功能就是这样。 看例子

 function doSomething() { } console.log(doSomething()); 

当您从then链中的函数返回Promisethen仅在解决了返回的Promise情况下才起作用。 如果发生异常,则在最后一个存在的情况下catch函数将起作用。 所以实际上你的代码就像

doSomething().then(function () {
  doSomethingElse();
  return undefined;
}).then(finalHandler); `undefined` is passed into the `finalHandler` function

并行操作如何,它们不是并行运行,而是如果代码then(...).then(...)顺序运行。 then这些将按顺序工作。 但是,如果您的doSomethingElse也返回Promise ,它将具有自己的链序列。 它的流独立于doSomething流。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM