Promise.all() 允许失败的替代方案? [复制]

Posted

技术标签:

【中文标题】Promise.all() 允许失败的替代方案? [复制]【英文标题】:Promise.all() Alternative that allows failure? [duplicate] 【发布时间】:2017-09-16 03:55:55 【问题描述】:

据我了解,Promise.all() 并行执行所有内容,并在任一 Promise 中的第一个错误实例返回错误。

现在,如果我想并行运行所有 Promise 并等待它们完成,即使其中一个失败了怎么办?

是否有我应该使用的 Promise 方法或模块?

我正在并行发送一堆用户 FCM 推送通知,并且如果其中任何一个失败,则 .then() 排队失败。

我在我的代码中这样做

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

【问题讨论】:

【参考方案1】:

你可以这样做:

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

这会将所有有错误的Promise 对象解析为结果数组中的null。您还可以使用.catch(error =&gt; error) 保留Error 对象,以便在最后检测故障,或解析为具有 status, result, error 属性的对象。

【讨论】:

谢谢,这看起来很棒! 使用Promise.all( ) 是不是最佳的好习惯,性能呢 这与使用Promise.all 完全没有包装器一样高效。您的承诺可能是异步的,因此 CPU 能力应该不是问题。内存方面,除非你有一个包含 100.000 个 promise 的数组,否则不要担心。 如果您没有在顶部看到关于 Promise.allSettled 的其他堆栈溢出的通知,请查看。 随意看看 Promise.allSettled() > Promise.allSettled() 方法返回一个在所有给定的承诺都已履行或拒绝后解决的承诺,并带有一组对象每个都描述了每个承诺的结果。 developer.mozilla.org/en-US/docs/Web/javascript/Reference/…

以上是关于Promise.all() 允许失败的替代方案? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

实现promise.all方法

promise.all的使用

JavaScript的Promise.all和Promise.race

JavaScript Promise.all 是不是有在成功和失败时触发的回调 [重复]

如何使用并区分Promise.all和Promise.race?

手写promise.all和race