节点.js异步模块问题

Node.js async module issue

本文关键字:问题 模块 异步 js 节点      更新时间:2023-09-26

我正在尝试使用异步模块来减少特定于 Node.js 的"回调地狱"。基本上,我正在尝试使用async.series从数据库中检索一些信息并将其显示在我的视图中。尽管如此,在我看来,我没有得到任何结果。

这是我到目前为止的代码:

// Search
exports.search = function(req, res) {
    var x = [];

        async.series([
            function(cb) {
                Lang.find({ lang: req.query.keyword }).sort({ verbal: -1 }).exec(function(err, langs) {              
                    cb(null, langs);
                });
            },
            function(cb) {
                Human.find({}, function(err, humans) {            
                    cb(null, humans);
                });
            }], 
            function(err, results) {
                if (err) {
                    res.send(500);
                }
                for(var i = 0; i < results[0].length; i++) {
                    for(var j = 0; j < results[1].length; j++) {
                        if(results[1][j]._id == results[0][i].human) {
                             x.push(results[1][j]);
                        }
                    }
                } 
                res.render('myView', { title: 'Search Results', humans: x });
            }
        );
    }

我首先想查询 Lang 模型 (MongoDB) 并找到与 req.query.keyword 匹配的记录。之后,我想查询人类模型并找到所有具有该特定语言技能的人类。此外,FOR 循环旨在消除我的数组中的重复项,因为人类可能有多种语言。

如果我正确理解您的代码,您可能希望改用async.waterfall。它将结果从一个函数作为参数传递给下一个函数。还可以进行一些其他优化:

async.waterfall([
  function(done) {
    Lang
      .find({ lang: req.query.keyword })
      .sort({ verbal: -1 }) // (not really useful)
      .select('human')      // not strictly necessary, but saves a bit of space
      .exec(done);          // short for : 
                            //   .exec(function(err, results) {
                            //     done(err, results);
                            //   });
  },
  function(langs, done) {
    // extract the 'human' property from each result
    var _ids = langs.map(function(lang) {
      return lang.human;
    });
    // perform a query finding all humans in the list of ids
    Human
      .find({ _id : { $in : _ids } })
      .exec(done);
  }
], function(err, humans) {
  if (err)
    return res.send(500);
  res.render('myView', {
    title : 'Search Results',
    humans: humans
  });
});

编辑:因为$in不保留顺序,这个答案表明使用$or会,请尝试将其作为第二个查询的替代方法:

  ...
  function(langs, done) {
    var query = langs.map(function(lang) {
      return { _id : lang.human };
    });
    Human
      .find({ $or : query })
      .exec(done);
  }
  ...