Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Promise.all() Alternative that allows failure? [duplicate]

As i understand it, Promise.all() executes everything in parallel and returns a error at the first instance of error in either of the Promises.

Now what if i want to run all promises in parallel and wait for them to complete even if one of them were to fail ?

Is there a Promise method or module i'm supposed to use ?

Im sending a bunch of users FCM push notifications in parallel and Failing the .then() queueing if any one of them fails is not intended.

I'm Doing this in my code

//then chain

    .then(()=>{
            let startChatPromises = [];
            for (let i = 0 ; i < queue_length ; i ++){
                startChatPromises.push(matchUsers(some_key,some_key));
            }
            return Promise.all(startChatPromises);
        }).then(()=>{// Continue processing even after failure ?});


let matchUsers = (room_id,...user_ids) => {

    let chat_key = admin.database().ref().child("chats").child(room_id).push().key;

    let participants = {};

    user_ids.forEach(user_id=> {
        participants[`${user_id}`] = true;
    });

    return admin.database().ref().child("chats").child(room_id).child(chat_key).update({
        "last_message_ts" : new Date().getTime(),
        "participants" : participants
    }).then(()=>{
        //Get Users
        let getFCMTokenPromises = [];
        user_ids.forEach(user_id => {
            getFCMTokenPromises.push(admin.database().ref("users").child(user_id).child("fcm_id").once('value'));
        });
        return Promise.all(getFCMTokenPromises);
    }).then(results => {
        // Send Push Notifications
        let tokens = [];
        results.forEach(snapshot=>{
            if (snapshot.val() !== undefined && snapshot.val() !== null && snapshot.val() !== "")
                tokens.push(snapshot.val());
        });
        const payload = {
            data: {
                NOTIFICATION_TYPE: 'START_CHAT',
                CHAT_UID: chat_key
            }
        };
        return admin.messaging().sendToDevice(tokens, payload);
    }).catch(()=>{
        return true;
    })
};
like image 587
Sanket Berde Avatar asked Apr 19 '17 18:04

Sanket Berde


People also ask

What happens to Promise all if one fails?

Promise.all fail-fast behaviorPromise.all is rejected if any of the elements are rejected. For example, if you pass in four promises that resolve after a timeout and one promise that rejects immediately, then Promise.all will reject immediately.

Does Promise all throw error?

As we can see in the output above, even though the promise2 function throws an error, the Promise. all() method does not get rejected, and the browser throws an unhandled error.

What is the difference between Promise all and Promise allSettled?

all() method returns an array as an output containing promise data inside several indexes. Promise. allSettled() method returns an array of objects and each of these objects further contains two properties further status and value.

What is alternative for Promise in JavaScript?

Async/await is an alternative syntax for promises that makes reading/writing async code even easier, but there are a few caveats you need to know about async/await or you may end up making your code worse.


1 Answers

You could do something like this:

function allSkippingErrors(promises) {
  return Promise.all(
    promises.map(p => p.catch(error => null))
  )
}

This will resolve all the Promise objects with errors to a null in the resulting array. You could also keep the Error object using .catch(error => error), to detect failures at the end, or resolve to an object with { status, result, error } properties.

like image 131
slezica Avatar answered Nov 06 '22 23:11

slezica