简体   繁体   中英

Handling individual errors when multiple promises pushed into an array in Javascript

I have multiple queries I am running using JS promises. I want to do some stuffs after those queries are run. I don't care if some of it failed, as long as I know it failed. However, in my below code when it fails the whole block of code doesn't run.

Below is my code:

//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'));

Then I run the below code:

// 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];

    }

But at times, some reference in the promises wont exist. When that happen, that promise fails. And the whole function is not executed. What I actually want is, some failure value or something still returned so I can handle it and continue with my logics.

Since Promise.all will reject if any of its component promises reject, you'll have to make sure none of them do. You can do that by adding a .catch handler to each promise:

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 */}));

Adding a catch to each promise individually is nice in that it will allow you to handle each one differently if you so choose. However, if you're using the same error handling code for each of them, you can avoid repeating yourself by using .map to add the handler to each promise instead:

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];
}

Depending on how you want to handle your errors, one approach may me more suitable than the other.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM