javascript - 将 reject() 跳过 Promise 中所有随后的 then()

标签 javascript promise

我一直很好奇,如果一个Promise在任何位置被rejected,下面的then()还会被执行吗?以下面的代码为例:

Promise.reject('reJECTed')
.then(() => {
    console.log('before resolve()');
    return Promise.resolve('reSOLVed');
})
.then((msg) => {
    console.log('reSOLVed inside 1st then()');
    console.log(msg);
}, (msg) => {
    console.log('reJECTed inside 1st then()');
    console.log(msg);
})
.then((msg) => {
    console.log('reSOLVing inside 2nd then()');
    console.log(msg);
}, (msg) => {
    console.log('reJECTing inside 2nd then()');
    console.log(msg);
})
.catch((msg) => {
    console.log('reJECTed in catch()');
    console.log(msg);
});

它会打印

reJECTed inside 1st then()
reJECTed
reSOLVing inside 2nd then()
undefined

在控制台上,这意味着第二个then()中的resolve()和最后一个catch()都没有执行。这是否意味着当遇到 reject() 时,then() 中的任何后续 resolve() 都会被完全跳过,直到发现拒绝为止?

感谢任何解释!

最佳答案

Does that mean when met reject(), any following resolve()s inside a then() is totally skipped until the rejection is caught?

是的。当 promise 拒绝时,链中的所有解析处理程序都会被跳过,直到某个拒绝处理程序处理拒绝并将 promise 链更改回已完成。

而且,如果您没有意识到,.then() 的第二个参数handler 是一个拒绝处理程序(与 .catch() 处理程序几乎相同)。

但是,请记住,如果您有拒绝处理程序但它没有 throw或返回一个被拒绝的 promise ,那么由于您已经“处理”了拒绝,链条将再次实现。与 try/catch 完全一样.如果你catch并且不重新抛出,然后处理异常,然后继续正常执行。

因此,在输出 reJECTed inside 1st then() 的拒绝处理程序中,您不会返回任何东西,因此此时 promise 链已实现。此时拒绝已被“处理​​”, promise 链现在切换到已完成状态。

这是您的代码的一些注释:

Promise.reject('reJECTed')
.then(() => {
    // this fulfilled handler is skipped because the promise chain is rejected here
    console.log('before resolve()');
    return Promise.resolve('reSOLVed');
})
.then((msg) => {
    // this fulfilled handler is skipped because the promise chain is rejected here
    console.log('reSOLVed inside 1st then()');
    console.log(msg);
}, (msg) => {
    // this reject handler is called because the promise chain is rejected here
    console.log('reJECTed inside 1st then()');
    console.log(msg);
    // because this does not rethrow or return a rejected promise
    // the promise chain switches to fulfilled
})
.then((msg) => {
    // this fulfilled handler is called because the promise chain is fulfilled now
    console.log('reSOLVing inside 2nd then()');
    console.log(msg);
}, (msg) => {
    // this reject handler is not called because the promise chain is fulfilled now
    console.log('reJECTing inside 2nd then()');
    console.log(msg);
})
.catch((msg) => {
    // this reject handler is not called because the promise chain is fulfilled now
    console.log('reJECTed in catch()');
    console.log(msg);
});

让我再举一个例子来说明 promise 链是如何切换状态的:

Promise.reject("Hello").then(val => {
    console.log("1: I am not called");
}).catch(err => {
    console.log("2: I am rejected");
    // rethrow to keep promise chain rejected
    throw err;
}).catch(err => {
    console.log("3: I am still rejected");
    // return normal value, promise chain switches to fulfilled
    return "GoodBye";
}).then(val => {
    console.log("4: Now back to fulfilled state");
}).catch(err => {
    console.log("5: Not called");
});

关于javascript - 将 reject() 跳过 Promise 中所有随后的 then(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42583589/

相关文章:

javascript - 在 TypeScript 中使用 Promises 的异步函数的正确错误模式

java - jsp中的考试类型问题

javascript - 为什么我的 InnerHTML 代码不会在表单字段中显示任何数据?

javascript - 实时更新有问题

javascript - 单击单选类型按钮?

javascript - 谷歌应用脚​​本,团队驱动的谷歌选择器

javascript - 在没有线程的情况下如何在 Javascript 中实现 Promise

node.js - Knex.js - Node 进程永远不会退出,如何优雅地关闭它 - 但只有当所有查询都得到解决时?

javascript - Promise 和延迟对象

node.js - 无法读取未定义的属性 'catch'