簡體   English   中英

如何對多個查詢使用異步並行

[英]How to use async parallel for multiple Queries

我是javascript新手。

我試圖使用async.parellel函數。 並獲取“ reviewArr”並返回。

請看我的代碼。

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。 批判,評論是模型(貓鼬模式)。

當我運行此代碼時,會收到此消息。 “任務不是功能”

請幫助我如何解決此錯誤? 問候。

您沒有正確設置功能。 期望的參數是帶有callback參數的function()包裝,當包含的異步函數完成時,該參數將傳遞給該參數。

您還真的只想要async.map而不是您在做什么,因為它的輸出是循環調用結果的數組。 因此,無需將結果推送到外部變量中:

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,而不是導入外部庫

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

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功能。

支持$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值傳遞給$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版本,對數據庫的“一個”或“兩個”實際調用。 完全不需要循環異步調用。


最后,如上所述,實際上並沒有必要,但是async.parallel的正確用法是:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM