node.js中的多个异步调用问题

时间:2015-08-05 18:29:35

标签: javascript node.js mongodb mongoose

我对node.js相当陌生,所以请原谅我的无知,我正在尝试的是循环遍历一组服务器并为每个服务器分配最多60个任务。但是,传入的任务数量可以是10到200之间的任何值。

所以我要做的就是将60个任务分配给第一台服务器,然后将60个任务分配给第二台服务器,依此类推。

我有以下功能,这似乎是非常错误的..

function mount_the_tasks(server_info){
    async.forEach(server_info, function(single_server, callback1){
        Tasks.find({task_status : 0}).limit(single_server.can_perform_tasks).exec(function(err, tasks_for_server){
            async.forEach(tasks_for_server, function(single_task, callback2){
                Tasks.findOneAndUpdate({_id : single_task._id}, {task_status : 1, server_id : single_server.instance_id}, function(err, numberAffected){
                    console.log(single_task.task_id+' -> '+single_server.instance_id);
                    callback2();
                });
            }, function(err){
                console.log('Moving to next server!');
                callback1();
            });
        });
    }, function(err){
        console.log('all done!');
    });
}

1 个答案:

答案 0 :(得分:0)

问题是你要并行浏览所有服务器。这意味着对于每个服务器,您将前60个活动任务分配给每个服务器,因为在下一个服务器迭代完成时,前一组任务尚未完成,因此它们的状态仍为0要解决这个问题,在迭代服务器时,你必须使用async.eachSeries,以便在转移到下一个服务器之前将任务标记为完成。

function mount_the_tasks(server_info){
    async.eachSeries(server_info, function(single_server, callback1){
        Tasks.find({task_status : 0}).limit(single_server.can_perform_tasks).exec(function(err, tasks_for_server){
            async.each(tasks_for_server, function(single_task, callback2){
                Tasks.findOneAndUpdate({_id : single_task._id}, {task_status : 1, server_id : single_server.instance_id}, function(err, numberAffected){
                    console.log(single_task.task_id+' -> '+single_server.instance_id);
                    callback2();
                });
            }, function(err){
                console.log('Moving to next server!');
                callback1();
            });
        });
    }, function(err){
        console.log('all done!');
    });
}

另一个选择是使用.skip()使每次迭代跳过前一个服务器处理的任务数。这应该比前一个选项快一点,假设您的服务器由于同时发送的请求数量而已经没有瓶颈。

function mount_the_tasks(server_info){
    var skip = 0;
    async.each(server_info, function(single_server, callback1){
        Tasks.find({task_status : 0}).limit(single_server.can_perform_tasks).skip(skip).exec(function(err, tasks_for_server){
            async.each(tasks_for_server, function(single_task, callback2){
                Tasks.findOneAndUpdate({_id : single_task._id}, {task_status : 1, server_id : single_server.instance_id}, function(err, numberAffected){
                    console.log(single_task.task_id+' -> '+single_server.instance_id);
                    callback2();
                });
            }, function(err){
                console.log('Moving to next server!');
                skip += single_server.can_perform_tasks;
                callback1();
            });
        });
    }, function(err){
        console.log('all done!');
    });
}