Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/39.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如果两个承诺同时解决,这是一个可能的竞争条件吗?_Javascript_Node.js_Asynchronous_Promise - Fatal编程技术网

Javascript 如果两个承诺同时解决,这是一个可能的竞争条件吗?

Javascript 如果两个承诺同时解决,这是一个可能的竞争条件吗?,javascript,node.js,asynchronous,promise,Javascript,Node.js,Asynchronous,Promise,我有两个异步操作: 将通知推送到IOS设备 将通知推送到ANDROID设备。 这两个操作由两个函数完成,它们返回两个不同的承诺。 执行这两个操作的调用函数只需要在两个承诺都已解决时返回(为简单起见,假设这些承诺从未被拒绝) 为了实现这一点,我编写了以下代码块。解析“sendIOSPushNotification”承诺后,我设置了一个标志,表示已触发IOS通知,并检查“sendAndroidPushNotification”是否已解析,如果已解析,则从调用函数解析承诺(p)。 同样,在解析“sen

我有两个异步操作:

  • 将通知推送到IOS设备
  • 将通知推送到ANDROID设备。 这两个操作由两个函数完成,它们返回两个不同的承诺。 执行这两个操作的调用函数只需要在两个承诺都已解决时返回(为简单起见,假设这些承诺从未被拒绝)
  • 为了实现这一点,我编写了以下代码块。解析“sendIOSPushNotification”承诺后,我设置了一个标志,表示已触发IOS通知,并检查“sendAndroidPushNotification”是否已解析,如果已解析,则从调用函数解析承诺(p)。 同样,在解析“sendAndroidPushNotification”时,检查“SendIOShusNotification”承诺的状态

    理想情况下,两个承诺中的一个将首先解决,最后解决的承诺将确保调用函数承诺(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;
    }
    

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

    两个Promise实例不可能同时解决。一个会先于另一个发生。您的情况需要使用
    Promise.all()
    来管理两个Promise解决方案的等待。由于nodejs应用程序中只有一个线程,所以这种情况无法发生;)在nodejs:)中不可能实现并发,但根据您的逻辑,如果没有iOS令牌或androud令牌,承诺将永远无法解决。@pierre是的,JS是明显同步的,但它允许基于任务的并发(但在这种情况下不会导致问题)。术语框架并不适合这里。此外,在事件循环级别上讨论时,区分“异步”和“同步”也没有意义,因为您编写的所有代码最终都在任务队列中的一个任务中。@Jonaswillms收到了您关于“框架”的说明,关于另一件事-我知道,只是试图做一个简单、友好的解释:)谢谢您的标记!