我正在尝试使用以下代码检索 2 个项目的信息和每个项目 (a、b、c( 的用户信息。但是,我有一个问题,它显示重复的结果和意外的输出。
- 查找项目 a
- 查找用户 a
- 查找用户 a
- 查找项 c
- 查找用户 c
- 结果
- 查找项目 b
- 查找用户 b
- 结果
- 查找用户 b
- 结果
(项目"c"只有 1 项(
我期待只看到一次结果。
var results = [];
var items = ['a', 'b', 'c'];
function async(item, callback) {
findSomething(2, item, function(err, items){
if (err) throw err;
console.log('findItem ' + item);
var item = [];
_.map(items, function(value, key) {
findSomethingElse(items[key].id, function(err, name){
if(err) throw err;
console.log('findUser ' + item);
item['name'] = name;
item['items'] = items[key];
callback(item);
});
});
});
}
function final() {
console.log('results');
// return results;
}
function series(item) {
if(item) {
async(item, function(result) {
results.push(result);
return series(items.shift());
});
} else {
return final();
}
}
series(items.shift());
正如建议的那样,我已经尝试使用异步模块并让这段代码正确显示项目和用户,但我不确定如何进行回调以在 done(( 函数中显示结果数组。
var results = [];
var items = ['a', 'b', 'c'];
async.each(items, findItem, function(err){
if(err) throw err;
});
function findItem(item) {
Bid.findBids(2, item, function(err, bids){
if (err) throw err;
async.each(bids, findUser, function(err){
if(err) throw err;
});
});
}
function findUser(item) {
User.findBidder(item.email, function(err, user){
if(err) throw err;
var bid = [];
bid['user'] = user;
bid['item'] = item;
results.push(bid);
});
}
function done() {
console.log('Results: ' + results);
return results;
}
以下是使用异步队列的可能解决方案:
var results = [];
var items = ['a', 'b', 'c'];
// We assume items[] isn't empty, and create a queue
// to process each item.
var itemQueue = async.queue(function (item, nextItem) {
// For each item get the bids
Bid.findBids(2, item, function(err, bids){
if (err) throw err;
// If no bids go to next item
if (bids.length === 0) {
nextItem();
} else {
// Otherwise loop through bids with another queue
var bidQueue = async.queue(function (bid, nextBid) {
User.findBidder(item.email, function(err, user){
if(err) throw err;
var bid = [];
bid['user'] = user;
bid['item'] = item;
results.push(bid);
nextBid();
});
});
// When all bids are done, go to next item.
bidQueue.drain = function() {
nextItem();
};
// place all bids on the queue for this item.
bidQueue.push(bids);
}
});
});
// When all items are done, print the results
itemQueue.drain = function () {
console.log('Results: ');
console.log(results);
}
// push all the items onto the queue - note that if items is
// empty, drain() will never be called!
itemQueue.push(items);