如何使用 hapijs 和 mongoose 在循环中 return 一个值

How to return a value once in a loop with hapijs and mongoose

我必须用猫鼬查询 MongoDB 获取的一些信息来填充我的 risultato json,所以在循环结束时我必须使用 hapijs return resultato控制器。 如果我在最后使用 return 我会出现这样的错误:

Error:reply interface called twice

如果我在循环外使用 return 它 return:

var risultato = {
"models": [],
}

这是我的代码:

Myfunction: function(request, reply) {

  var risultato = {
    "models": [],
  }

  for(var i=0; i<3; i++){
    Collections                 //this is a mongoose model
      .findOne()
      .where({_id: id]})
      .populate('models')
      .exec( function(err, result) {
         risultato.models.push.apply(risultato, result.models);
         console.log(risultato)
         return reply(risultato)

      });
  }
};

我能做什么?

您是一个 for 循环中的 运行 个异步查询,每个查询都在其处理程序中调用 reply() 方法。

需要使用异步循环,或者在返回前判断三个回调是否都被调用过的系统

Myfunction: function(request, reply) {

var risultato = {
"models": [],
}

for(var i=0; i<3; i++){
Collections                 //this is a mongoose model
  .findOne()
  .where({_id: id]})
  .populate('models')
  .exec( function(err, result) {


       risultato.models.push.apply(risultato, result.models);
       console.log(risultato)

       if (resultato.models.length === 3) //All callbacks have returned
       {
            reply(risultato);
       }

    });
}
}

最好的方法是使用 async 库。尽早开始使用它,以后就不会有问题了。

使用Async模块,同样的查询可以执行如下:

var async = require('async');

Myfunction: function(request, reply) {

  var queries = [];

  for(var i=0; i<3; i++) {

    queries.push(function(callback){

      Collections                 //this is a mongoose model
      .findOne()
      .where({_id: id]})
      .populate('models')
      .exec( function(err, result) {
         console.log(risultato)
         callback(err, result);
      });
    });

  }

  async.parallel(queries, function (err, result) {

    reply({models: result});
  })
};

你可以通过promiseFor wrapped by BlueBird(一个promise库)实现。

var Promise = require('bluebird');

var promiseFor = Promise.method(function(condition, action, value) {
    if (!condition(value)) return value;
    return action(value).then(promiseFor.bind(null, condition, action));
});

Myfunction: function(request, reply) {
    var risultato = {
        "models": [],
    }

    promiseFor(function(count) {
         return count < 3;
    }, function(count) {
         return Collections 
            .findOne()
            .where({_id: id]})
            .populate('models')
            .exec( function(err, result) {
                risultato.models.push.apply(risultato, result.models);
                console.log(risultato)
                return ++count;
             });
   }, 0).then(function() {
       reply(risultato);
   });

}