在 Nodejs 中,如何停止 FOR 循环直到 MongoDB 调用返回

2024-05-16

我正在研究下面的代码片段。我有一个名为“stuObjList”的 JSON 对象数组。我想循环遍历数组以查找具有特定标志集的特定 JSON 对象,然后进行数据库调用以检索更多数据。

当然,FOR 循环不会等待数据库调用返回并到达 j == length 的末尾。当数据库调用返回时,索引“j”超出了数组索引。我了解 Node.js 的工作原理,这是预期的行为。

这里的解决方法是什么?我怎样才能实现我想要实现的目标?

...............
...............
...............
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 https://github.com/caolan/async“是一个非常流行的模块,用于抽象异步循环并使代码更易于阅读/维护。例如:

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() https://github.com/caolan/async#forEach将为 StuObjList 中的每个元素“并行”调用迭代器函数(即,它不会等待一个迭代器函数完成对一个数组元素的调用,然后再对下一个数组元素调用它)。这意味着您无法真正预测迭代器函数(或更重要的是数据库调用)的运行顺序。最终结果:不可预测的优等生顺序。如果顺序很重要,请使用.forEachSeries() https://github.com/caolan/async#forEachSeries功能。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Nodejs 中,如何停止 FOR 循环直到 MongoDB 调用返回 的相关文章

随机推荐