Node / Express - 如何等待For Loop结束以响应JSON

时间:2013-11-12 19:13:34

标签: javascript node.js

我的快速应用程序中有一个函数在For循环中进行多个查询,我需要设计一个回调,当循环结束时用JSON响应。但是,我不知道如何在Node中做到这一点。这是我到目前为止所做的,但它还没有工作......

exports.contacts_create = function(req, res) {
  var contacts = req.body;
  (function(res, contacts) {
    for (var property in contacts) { // for each contact, save to db
       if( !isNaN(property) ) {      
           contact = contacts[property];
                var newContact  = new Contact(contact);
                newContact.user = req.user.id
                newContact.save(function(err) {
                   if (err) {  console.log(err) };
                }); // .save
       }; // if !isNAN
    }; // for
            self.response();
  })(); // function
}; // contacts_create

exports.response = function(req, res, success) {
    res.json('finished');
};

1 个答案:

答案 0 :(得分:2)

除了回调结构之外,您的代码还存在一些问题。

var contacts = req.body;
(function(res, contacts) {

   ...

})(); // function

^您要在参数列表中重新定义contactsres,但不传递任何参数,因此在您的函数rescontacts内将{{1} }}

另外,不确定undefined变量的来源,但也许你在别处定义了。

关于回调结构,你正在寻找这样的东西(假设联系人是一个数组):

self

但是,您可能需要考虑并行执行数据库保存。像这样:

exports.contacts_create = function(req, res) {
  var contacts = req.body;

  var iterator = function (i) {
    if (i >= contacts.length) {
      res.json('finished'); // or call self.response() or whatever
      return;
    }

    contact = contacts[i];
    var newContact  = new Contact(contact);
    newContact.user = req.user.id
    newContact.save(function(err) {
      if (err)
        console.log(err); //if this is really a failure, you should call response here and return

      iterator(i + 1); //re-call this function with the next index
    });

  };

  iterator(0); //start the async "for" loop
};

这样,在开始下一次数据库往返之前,您无需等待每次保存完成。

如果您不熟悉我使用var savesPending = contacts.length; var saveCallback = function (i, err) { if (err) console.log('Saving contact ' + i + ' failed.'); if (--savesPending === 0) res.json('finished'); }; for (var i in contacts) { ... newContact.save(saveCallback.bind(null, i)); } 的原因,那么基本上回调可以知道哪个联系人在发生错误时失败了。如果您需要参考,请参阅Function.prototype.bind