【问题标题】:How to return a value once in a loop with hapijs and mongoose如何使用 hapijs 和 mongoose 在循环中返回一个值
【发布时间】:2016-04-21 21:51:54
【问题描述】:

我必须用 MongoDB 使用 mongoose 查询获取的一些信息来填充我的 risultato json,所以在循环结束时,我必须使用 hapijs 控制器返回 risultato。 如果我在最后使用 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)

      });
  }
};

我能做什么?

【问题讨论】:

    标签: node.js mongodb for-loop mongoose hapijs


    【解决方案1】:

    您在 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});
      })
    };
    

    【讨论】:

    • 谢谢,我会使用它,因为这个解决方案有效,但它不是很好...... :)
    • 解决方案就是解决你写的查询,我已经提到过,最好的方法是使用异步循环。
    【解决方案2】:

    你可以通过promiseFor包裹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);
       });
    
    }
    

    【讨论】:

    • 它给了我这个错误 TypeError: Promise.method is not a function
    • 你的节点版本是多少?
    • 我的节点版本是4.0.0
    • 对不起,Promise.method 来自bluebird,这是一个承诺库。能否请您安装 bluebird var npm,然后重试?
    • @GrazianoDimatteo,我已经更新了我的答案。 Promise 将是 Node.js 中异步操作的一个不错的选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-11-06
    • 2016-05-21
    • 2021-11-30
    • 2016-01-30
    • 2021-05-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多