【问题标题】:How to skip promise in a chain如何跳过链中的承诺
【发布时间】:2017-06-19 00:59:11
【问题描述】:

我在一个 nodejs 项目中工作,想跳过链中的承诺。下面是我的代码。在第一个 promise 块中,它将解析一个值 {success: true}。在第二个块中,我想检查success 的值,如果为真,我想将值返回给被调用者并跳过该链中的其余承诺;如果值为假,则继续链。我知道我可以在第二个块上抛出错误或拒绝它,但我必须处理它不是错误情况的错误情况。那么我怎样才能在承诺链中实现这一点呢?我需要一个不带任何其他第三方库的解决方案。

new Promise((resolve, reject)=>{
    resolve({success:true});
}).then((value)=>{
    console.log('second block:', value);
    if(value.success){
        //skip the rest of promise in this chain and return the value to caller
        return value;
    }else{
        //do something else and continue next promise
    }
}).then((value)=>{
    console.log('3rd block:', value);
});

【问题讨论】:

  • 你不能......就像你不能从链条中间取出一个链接并认为你有一个链条......你有两个!当然,可以沿链发送和检测“特制”值
  • 您不能将值返回给调用者。调用 promise 的结果返回的是 promise 对象,而不是你返回的值。

标签: javascript node.js promise


【解决方案1】:

只需嵌套您想要跳过的链的一部分(其余部分在您的情况下):

new Promise(resolve => resolve({success:true}))
.then(value => {
    console.log('second block:', value);
    if (value.success) {
        //skip the rest of this chain and return the value to caller
        return value;
    }
    //do something else and continue
    return somethingElse().then(value => {
        console.log('3rd block:', value);
        return value;
    });
}).then(value => {
    //The caller's chain would continue here whether 3rd block is skipped or not
    console.log('final block:', value);
    return value;
});

【讨论】:

  • 我的承诺链中的其余部分很长。如果我这样做,我必须创建我不喜欢的嵌套承诺链。有没有更好的方法来做到这一点?
  • @ZhaoYi 这里嵌套没有错。您将语句嵌套在 if 中,不是吗?这是承诺链的一个条件分支,恕我直言,这是惯用的。见my answer to a similar question。
  • @ZhaoYi - 任何有条件执行的.then() 处理程序都必须嵌套,因为您正在创建主链的一个短子分支。你的链的其余部分可以继续在顶层很好(这个答案没有显示)。分支需要嵌套。
  • @jfriend00 已添加顶级。好主意。我也通过value 否则代码将没有意义。
【解决方案2】:

如果您不喜欢嵌套的想法,您可以将链的其余部分分解为一个单独的函数:

// give this a more meaningful name
function theRestOfThePromiseChain(inputValue) {
    //do something else and continue next promise
    console.log('3rd block:', value);

    return nextStepIntheProcess()
        .then(() => { ... });
}

function originalFunctionThatContainsThePromise() {
    return Promise.resolve({success:true})
        .then((value)=>{
            console.log('second block:', value);
            if(value.success){
                //skip the rest of promise in this chain and return the value to caller
                return value;
            }

            return theRestOfThePromiseChain(value);
        });
}

除此之外,真的没有办法在中途停止承诺。

【讨论】:

  • 一个单独的函数在技术上仍然是嵌套的。
  • @jib 也许从执行的角度来看,但就代码的格式化方式(我认为这是 OP 所关心的)而言,它避免了过多的嵌套和长时间的很难看出它们从哪里开始和结束的代码。
【解决方案3】:

如果您愿意,您还可以继续将错误沿链向下抛出到最终的 catch 块。

const test = () => {
  throw new Error('boo');
}

const errorHandler = (e) => { throw e };

Promise.resolve()
        .then(console.log('then1'))
        .then(() => test())
        .then(f => console.log('then2'), errorHandler)
        .then(f => console.log('then3'), errorHandler)
        .catch((err) => console.log('caught', err));

// whoo
// then1
// caught Error: boo

【讨论】:

    猜你喜欢
    • 2022-01-12
    • 2019-01-31
    • 2014-08-12
    • 1970-01-01
    • 2019-05-24
    • 2019-05-10
    • 2017-04-26
    • 1970-01-01
    • 2017-11-23
    相关资源
    最近更新 更多