[英]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.