首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何捕获ES6 Promise拒绝并完全停止流?

如何捕获ES6 Promise拒绝并完全停止流?
EN

Stack Overflow用户
提问于 2015-12-24 14:45:07
回答 3查看 2.2K关注 0票数 4

假设我有4个函数:runA()runB()runC()runD()

使用ES6 promises,在一个完全成功的运行中,所有这些都将一个接一个地运行:

代码语言:javascript
复制
runA()
.then(runB)
.then(runC)
.then(runD)

如果runArunB失败(拒绝或抛出),我想调用error1(),然后完全停止链(而不是调用runCrunD )。这让我觉得应该在.then promise链的末尾添加一个.catch()

代码语言:javascript
复制
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)。

代码语言:javascript
复制
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运行后调用,因为捕获的结果将缺省为resolve。我唯一的选择是让error1函数创建一个它总是拒绝的promise吗?

EN

回答 3

Stack Overflow用户

发布于 2016-02-12 23:02:39

不,让error1创建一个总是拒绝的承诺,不是你唯一的选择。

您可以利用.then接受两个参数的事实:

代码语言:javascript
复制
.then(onSuccess, onFailure)

当给出两个参数时,有一种被低估的效果,即onFailure onSuccess中的捕获失败。这通常是不可取的,除了这里,您可以使用此事实来分支您的决策树:

代码语言:javascript
复制
runA()
.then(runB)
.then(() => runC().then(runD), error1)
.catch(error2)

这就是你想要的。

  • 如果runArunB失败,则调用error1并停止链。
  • 如果runCrunD失败,则调用<代码>D19并停止链。

你也可以这样写它:

代码语言:javascript
复制
runA()
.then(runB)
.then(() => runC()
  .then(runD)
  .catch(error2),
error1)

代码语言:javascript
复制
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)
代码语言:javascript
复制
<div id="div"></div>

尝试在this fiddle中修改哪个失败。

票数 4
EN

Stack Overflow用户

发布于 2015-12-24 16:27:50

只使用一个.catch()有什么问题吗?您可以在catch回调(if (error1) error1() else if (error2) error2()...)中进行错误分类。抛出的Error对象可以有一条消息和一个名称(可以是您需要的类型,例如'RunCError‘)。

代码语言:javascript
复制
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(handleErrors)

function runA() {
    // ...

    if (err) {
        var error = new Error('Something is wrong...');
        error.name = 'RunAError';
        throw error;
    }
}

function runB() {
    // ...

    if (err) {
        var error = new Error('Something is wrong...');
        error.name = 'RunBError';
        throw error;
    }
}

function runC() {
    // ...

    if (err) {
        var error = new Error('Something is wrong...');
        error.name = 'RunCError';
        throw error;
    }
}

function runD() {
    // ...

    if (err) {
        var error = new Error('Something is wrong...');
        error.name = 'RunDError';
        throw error;
    }
}

function handleErrors(err) {
    if (err.name == 'RunAError') {
        handleAError();
    }

    if (err.name == 'RunBError') {
        handleBError();
    }

    // so on...
}
票数 1
EN

Stack Overflow用户

发布于 2016-12-08 16:41:55

我碰巧遇到了同样的问题,到目前为止,我的解决方案是显式地调用catch中的reject,比如js:https://jsbin.com/yaqicikaza/edit?js,console

代码片段

代码语言:javascript
复制
const promise1 = new Promise( ( resolve, reject ) => reject( 42 ) );

promise1
  .catch( ( err ) => console.log( err ) ) // 42 will be thrown here
  .then( ( res ) => console.log( 'will execute' ) ) // then branch will execute


const promise2 = new Promise( ( resolve, reject ) => reject( 42 ) );

promise2
  .catch( ( err ) => Promise.reject( ) ) // trigger rejection down the line
  .then( ( res ) => console.log( 'will not execute' ) ) // this will be skipped

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34448493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档