2017-09-04 1 views
0

javascriptで新しいです複数のクエリにasync parallelを使用する方法

私は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を使用しました。 Critique、Reviewはモデルです(mongooseスキーマ)。

私はこのコードを実行すると、私はこのメッセージが表示されます。

「タスクは関数ではありません」私はこのエラーを修正することができますどのように助けてください?よろしくです。 よろしくお願いします。

答えて

4

機能が正しく設定されていません。期待される引数は、ラッパーで、callback引数があり、含まれている非同期関数が完了したときに渡されます。それは、出力がループ呼び出しからの結果の配列ですだから

はまた、実際には、代わりにあなたが何をしているかの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); 
     } 
    ); 

    }); 
}); 

しかし、あなたが本当にここに約束を使用する必要があり、すべての正直ではなく

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

}); 

それとも、単に$inにすべてid値を渡す、ということはありません場合:

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

}); 

"1" または「どちらかを意味し、どのあなたのMongoDBのバージョンに応じてデータベースへの実際の呼び出しを2回行います。非同期呼び出しをループする必要はありません。


最後に、上記のすべてで説明したように、それは本当に必要はありませんが、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); 
     } 
    ) 
    }); 
}); 
+0

ベストの答えを見てきたもの。 また、非同期についての良い講義もあります。 ありがとうございます。あなたは[答えを受け入れる]検討するかもしれないfastworker399 @ – fastworker399

+0

(https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work)これは通常、それが実際に解決することを人々に示して問題に –

関連する問題