假设我有 4 个函数:runA()
、runB()
、runC()
和 runD()
.
使用 ES6 promise ,在一次完全成功的运行中,这些将一个接一个地运行:
runA()
.then(runB)
.then(runC)
.then(runD)
如果 runA
或 runB
失败(拒绝或抛出),我想调用 error1()
然后完全停止链(不调用 runC
或 runD
)。这让我觉得我应该在 .then
promise 链的最后添加一个 .catch()
:
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
)。
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
函数创建一个它总是拒绝的 promise 吗?
最佳答案
不,让 error1
创建一个始终拒绝的 promise ,不是您唯一的选择。
您可以利用 .then
接受两个参数的事实:
.then(onSuccess, onFailure)
当给定两个参数时,onFailure
会不 捕获 onSuccess
中的失败.这通常是不可取的,除了在这里,您可以使用这个事实来分支您的决策树:
runA()
.then(runB)
.then(() => runC().then(runD), error1)
.catch(error2)
这就是你想要的。
- 如果
runA
或runB
失败,则调用error1
并停止链。 - 如果
runC
或runD
失败,则调用error2
并停止链。
也可以这样写:
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>
尝试修改this fiddle中哪个失败.
关于javascript - 我如何捕获 ES6 Promise 拒绝并完全停止流程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34448493/