首页 > 解决方案 > JS Promises.all() - 如何防止“捕获”停止承诺链?

问题描述

给定一组 Promise 和 Promise.all() 语句,如果其中一个 Promise 失败,则整个链停止(它不等待任何后续 Promise 完成)并且 Promise.all().catch() 触发,但 Promise.all().then() 没有。

但是,如果各个 Promise 有自己的“catch”块,并且如果任何导致 Promise 失败的问题都可以在该 catch 块中修复,那么我们如何防止其余的 Promise 被忽略/失败,这样 Promise. all().then() 还会执行吗?有没有办法从 .catch() 块中“否定”错误,所以 Promises.all() 看不到它?我return Promise.resolve()在 .catch() 块的末尾尝试过,但它不起作用。

例子:

let promise_array = [];

let p = somePromisyFunction1()
    .then(() => { // Do something good })
    .catch(() => { // Handle the bad });
promise_array.push(p);

p = somePromisyFunction2()
    .then(() => { // Do something good })
    .catch(() => { // Handle the bad });
promise_array.push(p);

p = somePromisyFunction3()
    .then(() => { // Do something good })
    .catch(() => { // Handle the bad });
promise_array.push(p);


// ...
// More Promisy functions added to promise_array here...
// ...

Promise.all(promise_array)
    .then(() => { // We're all done! All promises fulfilled. })
    .catch(() => { // Something went wrong! });

在此示例中,如果 somePromisyFunctionX() 中的任何一个失败,则该函数的 .catch() 子句将执行,然后 Promise.all.catch() 子句也将立即执行,而无需等待任何后续的 Promise 完成.

但是,如果我们可以修复发生的任何坏事,在单个函数的 .catch() 子句中,我们如何防止 Promises.all().catch() 立即被触发,而是允许其余的 Promise 可以执行提前并实现?在某种程度上,在 .catch() 子句中,我们可以“否定”错误,因此看起来承诺实际上成功实现而不是看起来失败?

我可以使用 try/catch 块在 async/await 函数中执行此操作,但不确定如何使用 .then/.catch 执行此操作。

标签: javascriptnode.jspromise

解决方案


是的,您需要做的就是return从失败的承诺中捕获一些东西,它将作为解决方案“恢复”Promise.all

希望这能证明。没有整个链catchsomePromisyFunction2的 将失败(通过注释掉它来检查),但有了它,整个链就会成功并恢复值

let promise_array = [];

let p = somePromisyFunction1()
    //.then(() => { // Do something good })
   // .catch(() => { // Handle the bad });
promise_array.push(p);

p = somePromisyFunction2()
    //.then(() => { // Do something good })
    .catch((v) => "2 - " + v);
promise_array.push(p);

p = somePromisyFunction3()
    //.then(() => { // Do something good })
    //.catch(() => { // Handle the bad });
promise_array.push(p);


// ...
// More Promisy functions added to promise_array here...
// ...

Promise.all(promise_array)
    .then((v) => { console.log("all good",v) })
    .catch(() => { console.log("something bad") });
    
    
function somePromisyFunction1(){
  return new Promise(resolve => resolve("1"));
}

function somePromisyFunction2(){
  return new Promise((resolve,reject) => reject("oh no something went wrong!"));
}


function somePromisyFunction3(){
  return new Promise(resolve => resolve("3"));
}

您也可以选择使用allSettled而不是,all然后您可以内联处理故障

let promise_array = [];

let p = somePromisyFunction1()
    //.then(() => { // Do something good })
   // .catch(() => { // Handle the bad });
promise_array.push(p);

p = somePromisyFunction2()
    //.then(() => { // Do something good })
    //.catch((v) => "2 - " + v);
promise_array.push(p);

p = somePromisyFunction3()
    //.then(() => { // Do something good })
    //.catch(() => { // Handle the bad });
promise_array.push(p);


// ...
// More Promisy functions added to promise_array here...
// ...

Promise.allSettled(promise_array)
    .then((v) => { console.log("all good",v) })
    .catch(() => { console.log("something bad") });
    
    
function somePromisyFunction1(){
  return new Promise(resolve => resolve("1"));
}

function somePromisyFunction2(){
  return new Promise((resolve,reject) => reject("oh no something went wrong!"));
}


function somePromisyFunction3(){
  return new Promise(resolve => resolve("3"));
}


推荐阅读