2016-04-07 12 views
0

Zaman uyumsuz programlamada olduğu gibi geri aramaları ve sözleri kullandık. Burada sözler için kullanılabilecek bir sorunla karşılaştım. Ben google çok ama ben sorunumu çözdü hiçbir şey bulunamadı.Düğüm js'deki sözleri nasıl kullanabiliriz?

Burada Android cihazında push bildirimi göndermek için yaptığım kodum.

router.post('/check-notifications', function(req, res, next) { 

    var user_id = req.body.user_id; 

    var response = {}; 
    var gcm = require('push-notify').gcm({ 

     apiKey: gcm_apiKey, 
     retries: 0 
    }); 

    connection.query('select device_id from devices where user_id = '+ user_id, function (err, result) { 
     if (result.length) { 

      for (var i = 0; i < result.length; i++) { 

       console.log(i + 'before notify'); 
       gcm.send({ 

        registrationId: result[i]['device_id'], 
        data: result[0] 
       }); 

       console.log(i + 'before transmitted'); 
       gcm.on('transmitted', function (result, message, registrationId) { 
        console.log('transmitted'); 
       }); 

       gcm.on('transmissionError', function (error, message, registrationId) { 
        console.log(message); 
       }); 

       console.log(i + 'after notify'); 

      } 
     }   
    }); 

    response['success'] = true; 
    response['msg'] = 'sent successfully'; 
    res.json(response); 
}); 

Çıktı:

0before notify 
0before transmitted 
0after notify 
1before notify 
1before transmitted 
1after notify 
transmitted 
transmitted 
transmitted 
transmitted 

Ve Böyle olması gerektiğini düşünüyorum.

0before notify 
0before transmitted 
transmitted 
0after notify 
1before notify 
1before transmitted 
transmitted 
1after notify 
+0

Neden böyle düşünüyorsunuz? "gcm.send" eşzamansızdır ve döngü içi kod bildirim iletimini beklemez. Eşzamansız istekleri zincirlemek istiyorsanız, çözme için uyumsuz gibi Denetim akışı kitaplıkları kullanabilirsiniz. –

+0

Bu yüzden, konuştuğunuz uyumsuz kütüphaneyi kullanmanın farkında değilim. nasıl kullanabileceğimizi önerebilir misin? – iam

cevap

2

Bildirimleri zincirlemek için async.mapSeries yöntemini kullanabilirsiniz. Ben Promise akış kontrolü için Bluebird JS kullanılması önerilir

async.mapSeries(result, function(item, callback) { 
    gcm.send({ 
     registrationId: item['device_id'], 
     data: data 
    }); 
    gcm.on('transmitted', function(result, message, registrationId) { 
     console.log('transmitted'); 
     callback(null, message, registrationId); 
    }); 

    gcm.on('transmissionError', function(error, message, registrationId) { 
     callback(error, message, registrationId); 
    }); 
}, function (err, results) { 
    if (err) throw err; 
    response['success'] = true; 
    response['msg'] = 'sent successfully'; 
    res.json(response); 
}) 
+0

Sonuç dizisinde yalnızca 2 satırımız olduğu için neden günlük yazdırmayı dört kez göndermiyorum? Bu yüzden dört zaman bildirimi alındı. @ kazenorin'in cevabı ile aynı – iam

+1

Çünkü tüm örnekler, her sonuç için bir tane 'iletilen' olayına eklenir. Ve konsolda 'istek' istekleri var. –

2

: for döngü için değiştirin.

var Promise = require('bluebird'); // Require bluebird, and call it 'Promise', the code below is version 3.x syntax 

var connection = {'query': '???'}; // assuming `connection` is already defined somewhere else 
var gcm_apiKey = '???'; // assuming `gcm_apiKey` is already defined 

router.post('/check-notifications', function (req, res, next) { 

    var user_id = req.body.user_id; 

    var gcm = require('push-notify').gcm({ 
     apiKey: gcm_apiKey, 
     retries: 0 
    }); 

    // assuming `connection` is already defined somewhere else 
    // Make an async version of connection.query 
    connection.queryAsync = Promise.promisify(connection.query); 

    connection.queryAsync('select device_id from devices where user_id = ' + user_id) 
     // Bluebird's Promise.map would execute the following block once per result, asynchronously. 
     // The sequence of who runs first and who completes first is undefined 
     .map(function (result, i) { 
      // the `result` argument here is `result[i]` of the original code, since we're in the map context 

      // Here we have to create a promise to consume events 
      return new Promise(function (resolve, reject) { 

       console.log(i + 'before notify'); 
       gcm.send({ 
        registrationId: result['device_id'], 
        data: result // original code is written as result[0], which I don't quite understand. Always sending the first result? 
       }); 

       // This does not make sense console logging here, as it is not actually 'before transmitted' 
       // It's just binding onto the event 
       // console.log(i + 'before transmitted'); 
       gcm.on('transmitted', function (result, message, registrationId) { 
        // Check registrationId 
        if (registrationId === result['device_id']) { 
         console.log('transmitted'); 
         resolve(result); // use 'result' as the Promise's resolved value 
        } 
       }); 

       gcm.on('transmissionError', function (error, message, registrationId) { 
        // Check registrationId 
        if (registrationId === result['device_id']) { 
         console.log(message); 
         reject(message); // reject errors and send the message as the promise's reject reason 
        } 
       }); 

       // Technically, you should log it as "after event binding" 
       console.log(i + 'after notify'); 

      }); 
     }).then(function (results) { 
      // `results` should contain all the result from the 'transmitted' event 

      var response = {}; 
      response['success'] = true; 
      response['msg'] = 'sent successfully'; 
      res.json(response); 
     }); 

}); 

Not:, aslında az ya da çok yapılabilir herhangi kütüphaneler olmadan ama yerli Promises ile, ancak sözdizimi daha karmaşık olacaktır.

+0

İyi görünüyor. ancak sonuç dizisinde yalnızca 2 satırımız olduğu için neden günlük yazdırmayı dört kez iletmiyoruz? Bu yüzden dört zaman bildirimi alındı. – iam

+0

evet .. ekran görüntüsü: http://prntscr.com/ap5qi3 – iam

+0

Hem @Dima Fitiskin'in hem de benim cevabımda 4 kez aldığınızdan beri, muhtemelen 'iletilen' olayı iki kez yayılır. – kazenorin