如何对多个查询使用异步并行 [英] How to use async parallel for multiple Queries

查看:100
本文介绍了如何对多个查询使用异步并行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是javascript新手.

I am new in javascript.

我尝试使用async.parellel函数. 并获取"reviewArr"并返回.

I have tried to use async.parellel function. And get "reviewArr" and return it.

请查看我的代码.

app.get('/api/wherecritique/reviews/search/:author', function(req,res){
   var reviewArr = [];
   Critique.find({author:req.params.autho}, function(err,cris){
       var i =0;
       var f = function(reviewID)
      {
          Review.findOne({id:reviewID}, function(err, review)
          {
               reviewArr.push(review);
          }
      }
      var tasks = {};
      for(var j =0; j<cris.length; j++)
      {
          tasks['func'+j] = f(cris[j].reviewID);
      }
      async.parallel(tasks, function(err, results){
          console.log(results);
          res.json(reviewArr);
      });
  });
});

我使用了mongoose + express + node.js. 批判,评论是模型(猫鼬模式).

I used mongoose+express+node.js. Critique, Review are models(mongoose schema).

运行此代码时,会收到此消息. 任务不是功能"

When I run this code, I get this message. "task is not a function"

请帮助我如何解决此错误? 问候.

Please help how can i fix this error? Regards.

推荐答案

您没有正确设置功能.期望的参数是带有callback参数的function()包装器,当包含的异步函数完成时,该参数将传递给该容器.

You are not setting up the functions properly. The expected argument are function() wrappers with a callback argument which gets passed to when the contained async function completes.

您还真的只是想要 async.map 而不是您的身份这样做,因为它的输出是循环调用结果的数组.因此无需将结果推送到外部变量中:

You also really just want async.map instead of what you are doing, because it's output is an array of the results from the looped calls. So no need to push results into an external variable:

app.get('/api/wherecritique/reviews/search/:author', function(req,res) {

  Critique.find({author: req.params.author}, function(err,cris) {

    async.map(
      cris.map( c => c.reviewID ),
      function(id, callback) {
        Review.findOne({ id: id }, callback);
      },
      function(err,results) {
        if (err) throw err; // or something with err
        console.log(results);
        res.json(results);
      }
    );

  });
});

但是,老实说,您实际上应该在此处使用Promises,而不是导入外部库

But in all honesty you should really be using Promises here rather than import an external library

app.get('/api/wherecritique/reviews/search/:author', function(req,res) {

  Critique.find({author: req.params.author}, function(err,cris) {

    Promise.all(
      cris.map( c => Review.findOne({ id: c.reviewID }) )
    ).then( results => {
      console.log(results);
      res.json(results);
    }).catch( e => console.error(e) );

  });

});

或者以更现代的方式使用async/await:

Or in a more modern way with async/await:

app.get('/api/wherecritique/reviews/search/:author', async (req,res) => {

  try {       
    let cris = await Critique.find({author: req.params.author});

    let results = Promise.all(
      cris.map( c => Review.findOne({ id: c.reviewID }) )
    );
    console.log(results);
    res.json(results);
  } catch(e) {
    console.error(e);
  }

});

但是实际上,这与JavaScript完全无关,您确实应该使用MongoDB功能.

But in actual reality, this has nothing to do with JavaScript at all, and you really should be using MongoDB features.

使用 $lookup 进行支持:

app.get('/api/wherecritique/reviews/search/:author', async (req,res) => {

  try {       
    let results = await Critique.aggregate([
      { $match: { author: req.params.author } },
      { $lookup: {
        from: Review.collection.name,
        localField: 'reviewID',
        foreignField: 'id'
        as: 'reviews'
      }},
      { $unwind: '$reviews' }
    ]);

    results = results.map( r => r.reviews );
    console.log(results);
    res.json(results);

  } catch(e) {
    console.error(e);
  }

});

或者,如果没有,只需将所有id值传递给

Or if you don't have that, then simply passing all id values to $in:

app.get('/api/wherecritique/reviews/search/:author', async (req,res) => {

  try {       
    let cris = await Critique.find({ author: req.params.author });

    let results = await Review.find({ id: { $in: cris.map( c => c.reviewID ) } });
    console.log(results);
    res.json(results);

  } catch(e) {
    console.error(e);
  }

});

根据您的MongoDB版本,这意味着对数据库的一个"或两个"实际调用.完全不需要循环异步调用.

Which means either "one" or "two" actual calls to the database depending on your MongoDB version. No need to loop async calls at all.

最后,确实不需要上述所有说明,而是正确使用 async.parallel 为:

Finally, it's really not necessary as explained by all the above, but the correct usage of async.parallel would be:

app.get('/api/wherecritique/reviews/search/:author', (req,res) => {

  Critique.find({author: req.params.author}, (err,cris) => {

    var tasks = cris.map( c => (callback) =>
        Review.findOne({ id: c.reviewID }, callback);
    );

    async.parallel(
      tasks,
      (err,results) => {
        if (err) throw err; // or something
        console.log(results);
        res.json(results);
      }
    )
  });
});

这篇关于如何对多个查询使用异步并行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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