问题描述
假设我有4个函数: runA()
, runB()
, runC ()
和 runD()
。
Say I have 4 functions: runA()
, runB()
, runC()
and runD()
.
使用ES6承诺,完全成功运行,这些都将一个接一个地运行:
Using ES6 promises, in a completely successful run, these would all be run one after another:
runA()
.then(runB)
.then(runC)
.then(runD)
如果 runA
或 runB
失败(拒绝或抛出),我想调用 error1()
然后完全停止链(不是调用 runC
或 runD
)。这让我觉得我应该在 .then
promise链的最后添加一个 .catch()
:
If runA
or runB
fail (reject or throw), I would like to call error1()
and then completely stop the chain (not call runC
or runD
). This makes me think I should add a single .catch()
at the very end of the .then
promise chain:
runA()
.then(runB)
.then(runC) //won't get called if runA or runB throws
.then(runD) //won't get called if runA or runB throws
.catch(error1)
但如果 runC
失败,我想调用 error2()
并且仍然停止链(不是致电 runD
)。
But if runC
fails, I would like to call error2()
and still stop the chain (not call runD
).
runA()
.then(runB)
.catch(error1) //moved up to only handle runA and runB
.then(runC) //but now this gets called after error1() is run
.then(runD)
.catch(error2)
现在我在链中有2个 catch
调用, runC
将在 error1 正在运行,因为catch的结果将默认为 resolve
。我唯一的选择是让 error1
函数创建一个它总是拒绝的承诺吗?
Now that I have 2 catch
calls in the chain, runC
will get called after error1
is run since the result of the catch will default to a resolve
. Is my only option to have the error1
function create a promise that it always rejects?
推荐答案
不,让 error1
创建一个始终拒绝的承诺, 不 是您唯一的选择。
No, having error1
create a promise that always rejects, is not your only option.
您可以利用 .then
接受两个参数的事实:
You can exploit the fact that .then
takes two arguments:
.then(onSuccess, onFailure)
给出两个论点, onFailure
在中捕获失败的效果不明显的onSuccess
。这通常是不受欢迎的,除了在这里,您可以使用此事实来分支您的决策树:
When given two arguments, there's an under-appreciated effect that onFailure
will not catch failures in onSuccess
. This is usually undesirable, except here, where you can use this fact to branch your decision tree:
runA()
.then(runB)
.then(() => runC().then(runD), error1)
.catch(error2)
这可以满足您的需求。
- if
runA
或runB
失败,然后调用error1
并停止链。 - 如果
runC
或runD
失败,则error2
被调用并且链停止。
- if
runA
orrunB
fail, thenerror1
is called and chain stops. - if
runC
orrunD
fail, thenerror2
is called and chain stops.
您也可以这样写:
runA()
.then(runB)
.then(() => runC()
.then(runD)
.catch(error2),
error1)
var log = msg => div.innerHTML += "<br>" + msg;
// Change which one of these four rejects, to see behavior:
var runA = () => Promise.resolve().then(() => log("a"));
var runB = () => Promise.reject().then(() => log("b"));
var runC = () => Promise.resolve().then(() => log("c"));
var runD = () => Promise.resolve().then(() => log("d"));
var error1 = () => log("error1");
var error2 = () => log("error2");
runA()
.then(runB)
.then(() => runC().then(runD), error1)
.catch(error2)
<div id="div"></div>
尝试修改哪一个失败。
这篇关于我如何捕获ES6 Promise拒绝并完全停止流动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!