我如何捕获ES6 Promise拒绝并完全停止流动? [英] How do I catch ES6 Promise rejections and completely stop flow?

查看:68
本文介绍了我如何捕获ES6 Promise拒绝并完全停止流动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有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 or runB fail, then error1 is called and chain stops.
  • if runC or runD fail, then error2 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拒绝并完全停止流动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆