在 Javascript 中将多个 Promise 推入数组时处理单个错误

Posted

技术标签:

【中文标题】在 Javascript 中将多个 Promise 推入数组时处理单个错误【英文标题】:Handling individual errors when multiple promises pushed into an array in Javascript 【发布时间】:2019-01-17 09:57:04 【问题描述】:

我有多个使用 JS 承诺运行的查询。我想在这些查询运行后做一些事情。我不在乎其中一些是否失败,只要我知道它失败了。但是,在我下面的代码中,当它失败时,整个代码块都不会运行。

下面是我的代码:

//All the promises. These are basically multiple Firebase queries.
let promises = [];          
promises.push(db.ref('/gifts').orderByChild("active").equalTo("true").once('value'));
promises.push(db.ref('/coupons').orderByChild("active").equalTo("true").once('value'));
promises.push(db.ref('/shakes_user/' + uid).once('value'));
promises.push(db.ref('/shakes_user/' + uid + "/gift_allowed").once('value'));

然后我运行下面的代码:

// Wait for all promises to resolve
Promise.all(promises).then(function(res)   

    //I'm getting the right values below
    let gifts = res[0]; //gift
    let coupons = res[1]; //coupon
    let user_data = res[2];
    let gift_allowed = res[3];

    

但有时,promise 中的某些引用不存在。当这种情况发生时,这个承诺就会失败。并且整个功能都没有执行。我真正想要的是,一些失败值或仍然返回的东西,所以我可以处理它并继续我的逻辑。

【问题讨论】:

在需要检查失败的各个 promise 上使用 catch() @DougStevenson 将它推送到数组时我可以这样做吗?还是应该使用其他方法? 您可能希望在将回调放入数组之前附加回调。 【参考方案1】:

由于Promise.all 将拒绝其任何组件承诺拒绝,因此您必须确保它们都不拒绝。您可以通过向每个承诺添加 .catch 处理程序来做到这一点:

let promises = [];          
promises.push(db.ref('/gifts').orderByChild("active").equalTo("true").once('value').catch(err => /* handle error somehow */));
promises.push(db.ref('/coupons').orderByChild("active").equalTo("true").once('value').catch(err => /* handle error somehow */));
promises.push(db.ref('/shakes_user/' + uid).once('value').catch(err => /* handle error somehow */));
promises.push(db.ref('/shakes_user/' + uid + "/gift_allowed").once('value').catch(err => /* handle error somehow */));

为每个 promise 单独添加一个 catch 是很好的,因为如果你愿意,它可以让你以不同的方式处理每个 promise。但是,如果您对它们中的每一个都使用相同的错误处理代码,则可以通过使用 .map 将处理程序添加到每个 Promise 来避免重复自己:

Promise.all(promises.map(prom => prom.catch(err => /* handle error somehow */))).then(function(res)  // <-- note the map call
    //I'm getting the right values below
    let gifts = res[0]; //gift
    let coupons = res[1]; //coupon
    let user_data = res[2];
    let gift_allowed = res[3];

根据您希望如何处理错误,一种方法可能比另一种更适合我。

【讨论】:

以上是关于在 Javascript 中将多个 Promise 推入数组时处理单个错误的主要内容,如果未能解决你的问题,请参考以下文章

如何在 ES6 中将回调代码转换为 Promise [重复]

JavaScript中的Promise

在Javascript中将多个变量分配给相同的值?

在 JavaScript 中将多个数组值作为 url 变量传递

如何在 node.js 中将函数与 Promise 同步

在 Mongoose 查询中使用 javascript Promise