您沒有正確設置功能。期望的參數是function()
包含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);
}
});
或者,如果你沒有這一點,那麼簡單地通過了所有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);
}
)
});
});
最好的答案是我所見過。 也是關於異步的好的講座。 非常感謝。 – fastworker399
@ fastworker399您可能會考慮[接受答案](https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work),因爲這通常會向人們表明它確實是解決方案解決問題。 –