2016-09-01 19 views
0

私はNodejsと一緒に働いています。私はforループの後で完全な応答をするために約束を使用したいと思います。Qの約束とNodeJS非同期

exports.getAlerts = function(req,res,next){ 
var detected_beacons = []; 
if (!req.body || Object.keys(req.body).length == 0) { 
    res.status(401); 
    res.json({message:'No data sent'}); 
    return 
} 
var nets = req.body.networks; 
db.collection("beaconConfig", function(err, beaconConfigCollection){ 
    if (!err){ 
     var promises = []; 
     for(var i=0;i<nets.length;i++){ 
      var defer = q.defer(); 
      beaconConfigCollection.find({$or: [{"data.major" : nets[i].toString()},{"data.major" : nets[i]}], batteryLevel : {$lt : 70}}).toArray(function(errFind, saver){ 
       if (!errFind && saver && saver.length > 0){ 
        promises.push(defer.promise); 
        console.log("--------------------savers -------------------"); 
        console.log(saver); 
        for(var j=0; j<saver.length;j++){ 
         console.log("--------------------saver[j]-------------------"); 
         console.log(saver[j]); 
         var detected = {} 
         var major = saver[j].data.major; 
         detected.major = major; 
         console.log("--------------------detected -------------------"); 
         console.log(detected); 
         detected_beacons.push(detected); 
         defer.resolve(detected); 
        } 
       } 
      }); 
     } 
     q.all(promises).then(function(results){ 
      console.log("--------------------detected_beacons -------------------"); 
      console.log(detected_beacons); 
      res.json(detected_beacons); 
     }); 

    } else { 
     console.error(err); 
     res.status(500); 
     res.json({message:"Couldn't connect to database"}); 
    } 
});}; 

すべてconsoles.logは、最後の1ない限り、FIRST ONEです--- --- detected_beacons 1は、示されなければ、それが空で正常に動作します。

私は約束がうまくいかないと思っている理由です。私はvar q = require( 'q')を持っています。上のmongo接続は問題を返さない。

ありがとうございました。

+2

'promises'配列は非同期に設定されているためです。 – thefourtheye

+0

どうすればそれを解決できますか? – aserrin55

+1

'promises.push(defer.promise);'を非同期コールバックの外側に置くだけですか? Btw、あなたも[ループの問題で共通の閉鎖]を持っている(http://stackoverflow.com/q/750486/1048572)。別の関数で 'find 'の[promsification](http://stackoverflow.com/q/22519784/1048572)をより良く考えてください。 – Bergi

答えて

1

まず、約束事にどう対応するかについてawesome guide

まあ、憎しみは嫌いだけど、何も間違いはない(少なくとも、私はそう望む)。

'MongoDb for Node' documentationによれば、.toArray()は、このライブラリのほとんどのメソッドと同様にPromiseを返します。

exports.getAlerts = function(req, res, next) { 
    if (!req.body || Object.keys(req.body).length == 0) { 
     res.status(401); 
     res.json({message: 'No data sent'}); 
     return; 
    } 
    // db.collection returns a promise :) 
    return db.collection("beaconConfig").then(function(beaconConfigCollection) { 
     // you can use .map() function to put together all promise from .find() 
     var promises = req.body.networks.map(function(net) { 
      // .find() also returns a promise. this promise will be concat with all 
      // promises from each net element. 
      return beaconConfigCollection.find({ 
       $or: [{ 
        "data.major": net.toString() 
       }, { 
        "data.major": net 
       }], 
       batteryLevel: { 
        $lt: 70 
       } 
      }).toArray().then(function(saver) { 
       // you can use the .find() response to create an array 
       // with only the data that you want. 
       return saver.map(function(saverElement) { 
        // your result array will be composed using saverElement.data.major 
        return saverElement.data.major; 
       }); 
      }).catch(function(err) {}); 
     }); 
     // use q.all to create a promise that will be resolved when all promises 
     // from the array `promises` were resolved. 
     return q.all(promises); 
    }).then(function(results) { 
     console.log("results", results); 
    }).catch(function(err) {}); 
}; 

私はあなたに役立つことを願っています!