首页 > 解决方案 > 如果两个承诺同时解决,这是否是可能的竞争条件?

问题描述

我有两个异步操作:

  1. 向 IOS 设备推送通知。
  2. 向 ANDROID 设备推送通知。这两个操作由两个函数完成,它们返回两个不同的 Promise。执行这两个操作的调用函数只需要在两个承诺都被解决时才返回(为简单起见,假设这些承诺永远不会被拒绝)。

我编写了以下代码块来完成此操作。当“sendIOSPushNotification”承诺被解决时,我设置了一个标志,说明 IOS 通知被触发并检查“sendAndroidPushNotification”是否已经解决,如果是,则从调用函数中解决 promise(p)。同样,当“sendAndroidPushNotification”被解决时,检查“sendIOSPushNotification”承诺的状态。

理想情况下,两个promise 中的一个将首先解决,最后解决的promise 将确保调用函数promise(p) 得到解决。如果 'sendAndroidPushNotification' 和 'sendAndroidPushNotification' 同时解析,它会在竞态条件下解析吗?

function sendNotifs() {
let p = Q.defer();
if (iosDeviceTokens.length > 0) {
    self.sendIOSPushNotification(pUnitObj, alertObj, iosDeviceTokens)
        .then(function () {
            iosNotifAttempted = true;
            if (androidNotifAttempted) { //If promise to send push notification to Android is resolved then resolve 'p'
                p.resolve();
            }
        })
}

if (androidDeviceTokens.length > 0) {
    self.sendAndroidPushNotification(pUnitObj, alertObj, androidDeviceTokens)
        .then(function () {
            androidNotifAttempted = true;
            if (iosNotifAttempted) { //If promise to send push notification to IOS is resolved then resolve 'p'
                p.resolve();
            }
        })
}
return p.promise;
}

标签: javascriptnode.jsasynchronouspromise

解决方案


JS 是单线程的。

并发是通过使用事件循环和处理同步代码之间的异步操作来实现的,只要 CPU 可用(完全单脚解释,但这就是想法)。

您的情况需要使用Promise.all(),它对一系列承诺进行操作,并且仅在所有承诺都解决时才解决,或者在其中一个被拒绝时被拒绝。

let promises = [];
promises.push(self.sendIOSPushNotification(pUnitObj, alertObj, iosDeviceTokens));
promises.push(self.sendAndroidPushNotification(pUnitObj, alertObj, androidDeviceTokens));
Promises.all(promises).then( () => { /* your code when both are resolved */ } )

推荐阅读