如果then函数没有返回一个promise,为什么下一个函数会立即运行?

时间:2017-12-07 07:17:21

标签: javascript promise

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

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

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

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

2 个答案:

答案 0 :(得分:2)

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

<强> 1。什么都不返回。这会留下返回值undefined,这是父承诺的信号,即没有额外的异步操作在这里等待,所以承诺链可以继续运行链中的后续步骤

<强> 2。返回一个promise。这告诉父承诺你要在链中“插入”一个promise,并且在解除此promise之前不应该调用以下.then()个处理程序。该链条将基本上等待这一承诺。如果最终解决了这个新的承诺,将调用下一个.then()处理程序。如果这个新的承诺最终被拒绝,那么下一个.catch()处理程序将被调用。

第3。抛出异常。这告诉父承诺.then()处理程序中的操作失败,父承诺链立即被拒绝,下一个.catch()处理程序将被调用。

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

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

这只是一个完全独立的承诺链,除了这个其他承诺链的启动时间之外,根本没有与其他承诺链的连接。一旦启动,它就会独立于另一个链运行。这通常在承诺术语中称为“分支”。你分支成一个新的链。两者分开形式。如果两个分支都使用异步操作(他们可能会这样做),那些异步操作将是交错的,并且同时在飞行中。他们两人完成的时间完全不确定(因为他们的时间没有程序关系)。

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

在某些情况下,如果发生错误,您合法地不会更改程序行为。通常,当您在长序列结束时关闭文件,或者甚至只是在发生错误后尝试关闭文件时,您只需要尽最大努力关闭文件,而您实际上没有更多有用的文件如果关闭失败(除非记录失败),所以没有特别的理由尝试传播这种类型的失败。但是,这应该只是以非常深思熟虑的方式进行。 99.9999%的时间,错误应该传播回调用者并创建一个新的分支和独立的承诺链,这样不会将其错误传播回任何地方,因此它通常不是正确的编码策略。

答案 1 :(得分:1)

该函数不需要返回Promise。如果未显式返回任何内容,则默认返回undefined。 Javascript中的函数就是这样的。参见示例

function doSomething() {

}

console.log(doSomething());

当您从Promise链中的函数返回then时,then仅在已解析返回的Promise时才有效。如果发生异常,catch函数将在最后一个存在时起作用。 实际上你的代码就像

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

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