0

Express アプリに For ループ内で複数のクエリを作成する関数があり、ループが終了したときに JSON で応答するコールバックを設計する必要があります。しかし、ノードでこれを行う方法はまだわかりません。ここに私がこれまでに持っているものがありますが、まだ機能していません...

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');
};
4

1 に答える 1

3

コールバック構造だけでなく、コードにいくつかの問題があります。

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

   ...

})(); // function

^パラメータ リストでcontactsandresを再定義していますが、引数を渡していないため、関数内ではresandcontactsになります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));
}

これにより、データベースへの次のラウンドトリップを開始する前に、各保存が完了するのを待つ必要がなくなります。

を使用した理由がよくわからない場合はsaveCallback.bind(null, i)、基本的に、エラーが発生した場合にコールバックが失敗した連絡先を認識できるようにするためです。参照が必要な場合は、Function.prototype.bindを参照してください。

于 2013-11-12T19:35:28.863 に答える