【问题标题】:Asynchronous add to array in NodejsNodejs中的异步添加到数组
【发布时间】:2015-08-18 04:17:41
【问题描述】:
 var veh = [];
 app.get('/updateProf', isLoggedIn, function(req, res) {


     for (var i = 0; i < req.user.local.vehicles.length; i++){
           Vehicles.findById(req.user.local.vehicles[i], function(err, vehicle) {
              veh.push(vehicle);
              console.log("GET Json: " + veh);

            });
     }
     console.log(veh);
     res.json(veh);
     veh.length = 0;
});

所以我正在执行获取请求以获取用户拥有的所有车辆并返回其 json,刷新后它工作正常,但是当我转到页面时,它在初始加载时显示一个空数组,如果我刷新页面,数组被填充。我认为这个问题与异步有关,但我很难以这种方式思考,需要一些关于如何解决这个问题的建议。

【问题讨论】:

    标签: javascript arrays node.js asynchronous


    【解决方案1】:

    如果您使用的是更新版本的 Mongoose,则可以直接使用 Mongoose 为每个查询返回的 Promises

    例如,您的查询可以简化为

    Vehicles.find({ _id: {'$in': req.user.local.vehicles }})
      .exec()
      .then(function(vehicleArr) {
        res.json(vehicleArr);
      });
    

    请注意,我使用 $in 运算符将您的循环直接转换为 IN 条件,该条件采用您要比较的数组(在本例中,它是一个 ID 数组)

    then() 函数仅在查询完成时执行。

    【讨论】:

      【解决方案2】:

      Async 是一个处理这个问题的实用程序库。

       var async = require('async');
      
       app.get('/updateProf', isLoggedIn, function(req, res) {
         async.map(req.user.local.vehicles, function(vehicle, cb){
           Vehicles.findById(vehicle, function(err, vehicle) {
             if (err) cb(err, null);
             console.log('GET Json: ' + vehicle);
             cb(null, vehicle);
           });
         }, function (err, results) {
           console.log(results);
           res.json(results);     
         });
      
      });
      

      【讨论】:

        【解决方案3】:

        是的!!

        在返回 JSON 之前,您必须等待所有回调完成。

        一种解决方案是记录已执行的回调数量,当所有回调都已执行时,您可以返回 JSON。

         var veh = [];
         app.get('/updateProf', isLoggedIn, function(req, res) {
         number_processed = 0;
         total = req.user.local.vehicles.length;
        
         for (var i = 0; i < req.user.local.vehicles.length; i++){
               Vehicles.findById(req.user.local.vehicles[i], function(err, vehicle) {
                 if(!err){
                     veh.push(vehicle);
                 }
                 number_processed  = number_processed  + 1;
                 if(number_processed === total){
                     res.json(veh);
                 }
                 console.log("GET JSON: " + veh);
              });
         }
         veh.length = 0;
         });
        

        【讨论】:

        • 所以这里唯一要做的改变是我们跟踪 number_processed,并且在数组的长度等于我们推送的数量之后,我们可以返回 json。所以像这样编程的想法是顺序很重要,并且必须跟踪回调。非常感谢,我认为这对我还必须编写的其他功能有很大帮助!
        • 这就是库喜欢异步抽象的地方。很高兴知道它们在幕后是如何工作的,但您不想每次都编写这种代码。这就是你应该使用异步的原因,Achromes 的回答也非常好,他访问数据库一次而不是车辆中的每个项目。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-11-30
        • 2018-03-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-14
        • 1970-01-01
        相关资源
        最近更新 更多