简体   繁体   English

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

[英]multiple async call issue in node.js

I'm fairly new to node.js so kindly forgive my ignorance, what I'm trying to do is loop through an array of servers and allocate a maximum of 60 tasks to each server. 我对node.js相当陌生,所以请原谅我的无知,我想要做的是循环遍历一系列服务器,并为每个服务器最多分配60个任务。 However the incoming number of tasks can be anything between 10 to 200. 但是,传入的任务数量可以在10到200之间。

So what I'm looking to do assign 60 tasks to the first server, then the next 60 tasks to second server and so on. 因此,我希望将60个任务分配给第一台服务器,然后将接下来的60个任务分配给第二台服务器,依此类推。

I have the following function, which seems to go horribly wrong.. 我有以下功能,这似乎出了问题。

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!');
    });
}

The problem is you are going through all of the servers in parallel. 问题是您正在并行浏览所有服务器。 What this means is for each server, you're assigning the first 60 active tasks to each because by the time the next server is iterated through, the previous set of tasks aren't done yet so their status is still 0. To fix this, you'll have to use async.eachSeries instead when iterating over the servers so that the tasks are marked complete before moving on to the next server. 这意味着对于每个服务器,您要为每个服务器分配前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!');
    });
}

Another option would be to use .skip() to cause each iteration to skip the number of tasks handled by the previous server. 另一个选择是使用.skip()来使每次迭代跳过由先前服务器处理的任务数。 This should be a little bit faster than the previous option assuming your server isn't already bottlenecked due to the number of requests being sent simultaneously. 假定由于同时发送的请求数量尚未使服务器成为瓶颈,这应该比上一个选项要快一点。

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!');
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM