在nodejs中,如何停止FOR循环,直到mongodb调用返回 [英] in nodejs, how to stop a FOR loop until mongodb call returns

查看:106
本文介绍了在nodejs中,如何停止FOR循环,直到mongodb调用返回的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请看下面的代码片段。我有一个名为stuObjList的JSON对象数组。我想通过数组循环查找具有特定标志位的特定JSON对象,然后进行db调用以检索更多数据。

Please look at the code snippet below. I have an array of JSON objects called 'stuObjList'. I want to loop thru the array to find specific JSON objects with a certain flag set, and then make a db call to retrieve more data.

当然,FOR循环并不等待db调用返回并到达结尾的j == length。而当db调用返回时,索引'j'超出了数组索引。我明白node.js的工作原理,这是预期的行为。

Ofcourse, the FOR loop doesn't wait for the db call to return and reaches the end of with j == length. And when the db call returns, the index 'j' is beyond the array index. I understand how node.js works and this is the expected behavior.

我的问题是,这里有什么工作。我如何实现我想要实现的目标?谢谢,--su

My question is, what is the work around here. How can I achieve what I am trying to achieve? Thanks, --su

...............
...............
...............
else
{
  console.log("stuObjList.length: " + stuObjList.length);
  var j = 0;
  for(j = 0; j < stuObjList.length; j++)
  {
    if(stuObjList[j]['honor_student'] != null)
    {     
      db.collection("students").findOne({'_id' : stuObjList[j]['_id'];}, function(err, origStuObj)
      {
        var marker = stuObjList[j]['_id'];
        var major = stuObjList[j]['major'];
      });
    }

    if(j == stuObjList.length)
    {
      process.nextTick(function()
      {
        callback(stuObjList);
      });
    }
  }
}
});


推荐答案

异步是一个非常受欢迎的模块,用于抽象化异步循环,并使您的代码更易于阅读/维护。例如:

"async" is an very popular module for abstracting away asynchronous looping and making your code easier to read/maintain. For example:

var async = require('async');

function getHonorStudentsFrom(stuObjList, callback) {

    var honorStudents = [];

    // The 'async.forEach()' function will call 'iteratorFcn' for each element in
    // stuObjList, passing a student object as the first param and a callback
    // function as the second param. Run the callback to indicate that you're
    // done working with the current student object. Anything you pass to done()
    // is interpreted as an error. In that scenario, the iterating will stop and
    // the error will be passed to the 'doneIteratingFcn' function defined below.
    var iteratorFcn = function(stuObj, done) {

        // If the current student object doesn't have the 'honor_student' property
        // then move on to the next iteration.
        if( !stuObj.honor_student ) {
            done();
            return; // The return statement ensures that no further code in this
                    // function is executed after the call to done(). This allows
                    // us to avoid writing an 'else' block.
        }

        db.collection("students").findOne({'_id' : stuObj._id}, function(err, honorStudent)
        {
            if(err) {
                done(err);
                return;
            }

            honorStudents.push(honorStudent);
            done();
            return;
        });
    };

    var doneIteratingFcn = function(err) {
        // In your 'callback' implementation, check to see if err is null/undefined
        // to know if something went wrong.
        callback(err, honorStudents);
    };

    // iteratorFcn will be called for each element in stuObjList.
    async.forEach(stuObjList, iteratorFcn, doneIteratingFcn);
}

所以你可以这样使用:

getHonorStudentsFrom(studentObjs, function(err, honorStudents) {
    if(err) {
      // Handle the error
      return;
    }

    // Do something with honroStudents
});

请注意,。forEach()将在stuObjList并行中为每个元素调用迭代器函数(即,在调用之前不会等待一个迭代器函数完成调用一个数组元素它在下一个数组元素上)。这意味着您无法真正预测迭代器的运行顺序(或更重要的是数据库调用)的运行顺序。最终结果:不可预测的荣誉学生顺序。如果订单非常重要,请使用 .forEachSeries()功能。

Note that .forEach() will call your iterator function for each element in stuObjList "in parallel" (i.e., it won't wait for one iterator function to finish being called for one array element before calling it on the next array element). This means that you can't really predict the order in which the iterator functions--or more importantly, the database calls--will run. End result: unpredictable order of honor students. If the order matters, use the .forEachSeries() function.

这篇关于在nodejs中,如何停止FOR循环,直到mongodb调用返回的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆