I am pushing the data in messages_filtered array but when I try to get it in call back its always empty.I am pushing data two time in async loop. retMessages is created from messages_filtered, but its empty so retMessages is always empty.
Service.poll = function(user, callback) {
var messages_filtered = [];
async.forEach(activeAccountsFor(user), function(acct, done) {
graph.setAccessToken(acct.accessToken);
var connections = ['feed', 'links', 'tagged', 'posts', 'notes', 'inbox', 'outbox'];
var args = acct.updated_time ? {since: acct.updated_time - 3000} : {};
args['date_format']= 'U';
User.markAsUpdated(user._id);
User.markAccountAsUpdated(user._id, acct.userID);
async.forEach(connections, function(connection, next) {
graph.setOptions(options).get('me/' + connection, args,
function(err, feed) {
if (err) {
winston.log('error', 'Error in connection ');
return done();
}
async.forEach(feed.data, function(datum, onward) {
profanity_service.analyzeFeedItem(datum, function(err, result) {
if(!_.isUndefined(datum.comments)){
if(!_.isUndefined(datum.comments.data) && !_.isEmpty(datum.comments.data) ){
_.each(datum.comments.data, function(data){
if(moment(data.created_time).unix() >= user.updated_time){
profanity_service.analyzeFeedItem(data, function(err, result) {
if(!err && result){
if (result.isProfane){
messages_filtered.push(result);
}
}
});
}
});
}
}
if(!err && result){
if (result.isProfane) {
messages_filtered.push(result);
}
}
onward(err);
});
}, next);
});
}, done);
}, function(err) {
console.log('messages_filtered.length ' + messages_filtered.length);
if (messages_filtered.length > 0) {
var retMessages = [];
_.each(messages_filtered, function(message) {
if (!hasMessage(retMessages, message)) {
retMessages.push(message)
Message.flag(user._id, message);
}
});
user.notify(retMessages);
}
callback(err);
});
};
Well, you've got many asynchrounous actions nested, and some are executed after you went on with the outer loop :-) Specifically, you forgot to delay the onward
call until the innermost profanity_service.analyzeFeedItem
is done. It should be
… function(datum, onward) {
profanity_service.analyzeFeedItem(datum, function(err, result) {
if(!err && result){
if (result.isProfane) {
messages_filtered.push(result);
}
}
if(!_.isUndefined(datum.comments)
&& !_.isUndefined(datum.comments.data)
&& !_.isEmpty(datum.comments.data)
) {
async.forEach(datum.comments.data, function(data, forward){
// ^^^^^^^^^^^^^
if(moment(data.created_time).unix() >= user.updated_time){
profanity_service.analyzeFeedItem(data, function(err, result) {
if(!err && result){
if (result.isProfane){
messages_filtered.push(result);
}
}
forward(err);
});
} else {
forward();
}
});
} else {
onward(err);
}
} …
Btw, it looks odd that you analyze the datum.comments.data
in the callback of analyzing datum
- does it modify its input object? Or can you parallel them?
Also, it would be helpful to restructure your callback tree into individual functions with descriptive names that are declared elsewhere. Especially the repeated callback for profanity_service.analyzeFeedItem
which pushes result
s on the array would profit from that.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.