在 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 [重复]