简体   繁体   English

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

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

Inside of a then() function, if I didn't return a promise but calling the function directly. 在then()函数内部,如果我没有返回承诺而是直接调用该函数。

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

I know doSomethingElse & finalHandler will run in parallel then instead of running sequentially. 我知道doSomethingElse & finalHandler将并行运行,而不是顺序运行。 But I am still not sure why is that exactly? 但是我仍然不确定为什么会这样吗?

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

When you run code in a .then() handler, you get the following design choices: .then()处理程序中运行代码时,将获得以下设计选择:

1. Return nothing. 1.什么也不返回。 That leaves the return value undefined and that is a signal to the parent promise that there is no additional asynchronous operation to wait for here so the promise chain can continue running the next steps in the chain. 这使返回值保持undefined ,这是向父级诺言的信号,即此处没有其他异步操作可以等待,因此诺言链可以继续运行链中的后续步骤。

2. Return a promise. 2.兑现承诺。 This tells the parent promise that you want to "insert" a promise into the chain and the following .then() handlers should not be called until this promise is resolved. 这告诉父承诺,您希望将承诺“插入”到链中,并且在解决此承诺之前,不应调用以下.then()处理函数。 The chain will essentially wait for this promise. 连锁店实际上将等待这个承诺。 If this new promise is ultimately resolved, the next .then() handler will get called. 如果此新承诺最终得以解决,则将调用下一个.then()处理函数。 If this new promise is ultimately rejected, the next .catch() handler will get called. 如果此新承诺最终被拒绝,则将调用下一个.catch()处理函数。

3. Throw an exception. 3.引发异常。 This tells the parent promise that the operation in the .then() handler failed and the parent promise chain immediately becomes rejected and the next .catch() handler will get called. 这告诉父母承诺,在操作.then()处理程序失败,家长许诺链立即成为拒绝,接下来的.catch()处理程序将被调用。

So, in your case, if doSomethingElse() is an asynchronous operation and you don't return a promise that is connected with that asynchronous operation, then you've just "branched" your promise chain into two separate chains. 因此,在您的情况下,如果doSomethingElse()是异步操作,并且没有返回与该异步操作相关的promise,那么您只是将您的promise链“分支”为两个单独的链。 The main parent chain will continue calling the next .then() handler because you returned nothing. 主父链将继续调用下一个.then()处理函数,因为您什么也没有返回。 Meanwhile, your doSomethingElse() function is essentially its own parallel promise chain. 同时, doSomethingElse()函数本质上是其自己的并行诺言链。 It could even have it's own .then() handlers as in: 它甚至可以拥有自己的.then()处理程序,如下所示:

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

That would just be a completely separate promise chain that would have no connection at all to the other promise chain except for the timing of when this other promise chain was started. 那只是一个完全独立的承诺链,除了另一个承诺链何时开始的时间之外,它与另一个承诺链根本没有任何联系。 Once it starts, it runs independently from the other chain. 一旦启动,它将独立于其他链条运行。 This is typically referred to as "branching" in promise terminology. 这在承诺术语中通常称为“分支”。 You branch into a new chain. 您进入一个新的链条。 The two run separate form one another. 两者相互独立运行。 If both branches use asynchronous operations (which they presumably do), those asynchronous operations would be interleaved and both in flight at the same time. 如果两个分支都使用异步操作(大概是这样做的),则这些异步操作将被交错并同时运行。 The timing of when they both finished would be completely indeterminate (since they have no programmatic relationship in their timing). 他们俩什么时候完成的时间是完全不确定的(因为他们在时间上没有程序关系)。

Branching to a completely independent promise chain like this is usually a programming error and some promise implementations may report a likely programming error in the console. 像这样分支到一个完全独立的promise链通常是一个编程错误,某些promise实现可能会在控制台中报告可能的编程错误。 The reason this is usually an error is there is no way for anyone outside this code to have any way to monitor or catch errors in the branched and independent promise. 这通常是错误的原因是,此代码之外的任何人都无法以任何方式监视或捕获分支的独立承诺中的错误。 And promises without error handling are bad. 没有错误处理的承诺是不好的。 They eat errors silently. 他们默默地吃错了。

There are certain cases where you legitimately don't change your program behavior if an error happens. 在某些情况下,如果发生错误,则您合理地不更改程序行为。 Often times when you're closing a file at the end of a long sequence or even just trying to close files after errors have occurred, you just want to make your best efforts to close the file and you don't really have anything more useful to do if the close fails (except perhaps log the failure) so there's no particular reason to try to propagate back that type of failure. 通常,当您以较长的顺序结束文件时,甚至只是尝试在发生错误后关闭文件时,您只是想尽最大的努力来关闭文件,而实际上并没有什么用处如果关闭失败(可能记录失败除外),则可以执行此操作,因此没有特殊原因尝试传播回这种类型的失败。 But, this should only be done in a very thoughtful way. 但是,这只能以非常周到的方式进行。 99.9999% of the time, errors should be propagated back to the caller and creating a new branched and independent promise chain like this does not propagate its errors back anywhere so it's usually not the right coding strategy. 在99.9999%的时间中,错误应传播回调用者并创建一个新的分支且独立的Promise链,因为这样不会将其错误传播回任何地方,因此通常不是正确的编码策略。

The function does not need to return a Promise . 该函数不需要返回Promise If nothing was explicitly returned, by default undefined is returned. 如果未明确返回任何内容,则默认返回undefined Functions in Javascript work like that. Javascript中的功能就是这样。 See the example 看例子

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

When you return a Promise from the function in the then chains, then will work only if the returned Promise is resolved. 当您从then链中的函数返回Promisethen仅在解决了返回的Promise情况下才起作用。 If an exception was occurred, the catch function will work if the last exists. 如果发生异常,则在最后一个存在的情况下catch函数将起作用。 So actually your code is like 所以实际上你的代码就像

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

What about the parallel, they will work not in parallel, but sequentially if the code is then(...).then(...) . 并行操作如何,它们不是并行运行,而是如果代码then(...).then(...)顺序运行。 These then work sequentially. then这些将按顺序工作。 But if your doSomethingElse also returns a Promise , it will have its own sequence of chain. 但是,如果您的doSomethingElse也返回Promise ,它将具有自己的链序列。 It's flow is independent from the doSomething flow. 它的流独立于doSomething流。

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

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