我想,你想要的是:
function foo()
{
while (count < 10)
{
process.nextTick(doSometing);
count ++;
}
}
process.nextTick 将安排在事件循环的下一个滴答时执行doSometing。因此,这段代码不会立即切换到doSometing,而是安排执行并首先完成foo。
您也可以试试setTimeout(doSometing,0) 和setImmediate(doSometing)。他们将允许在执行doSometing 之前发生I/O 调用。
将参数传递给doSomething
如果你想将一些参数传递给doSomething,那么最好确保它们被封装并且在doSomething被执行之前不会改变:
setTimeout(doSometing.bind(null,foo,bar),0);
在这种情况下,doSometing 将使用正确的参数调用,即使 foo 和 bar 将被更改或删除。但是,如果 foo 是一个对象并且您更改了它的一个属性,这将不起作用。
有哪些替代品?
如果您希望doSomething 并行执行(不仅仅是异步,而是实际上是并行执行),那么您可能对一些作业处理解决方案感兴趣。推荐你看kickq:
var kickq = require('kickq');
kickq.process('some_job', function (jobItem, data, cb) {
doSomething(data);
cb();
});
// ...
function foo()
{
while (count < 10)
{
kickq.create('some_job', data);
count ++;
}
}
kickq.process 将创建一个单独的进程来处理您的作业。所以,kickq.create 只会注册要处理的作业。
kickq 使用redis 对作业进行排队,没有它就无法工作。
使用 node.js 内置模块
另一种选择是使用Child Process 构建您自己的作业处理器。生成的代码可能如下所示:
var fork = require('child_process').fork,
child = fork(__dirname + '/do-something.js');
// ...
function foo()
{
while (count < 10)
{
child.send(data);
count ++;
}
}
do-something.js 这是一个单独的.js 文件,带有doSomething 逻辑:
process.on('message', doSomething);
实际代码可能更复杂。
您应该注意的事项
Node.js 是单线程的,所以它一次只执行一个函数。它也不能使用超过一个 CPU。
Node.js 是异步的,因此它能够通过在多个函数之间切换来一次处理多个函数。在处理具有大量 I/O 调用的函数时,它非常有效,因为它是较新的块。因此,当一个函数等待来自 DB 的响应时,会执行另一个函数。但node.js 不是阻塞 CPU 使用率高的任务的好选择。
可以使用child_process 和cluster 等模块在node.js 中进行真正的并行计算。 child_process 允许您启动一个新的node.js 进程。它还创建了父进程和子进程之间的通信通道。集群允许您运行相同进程的集群。当您处理http 请求时,它真的很方便,因为cluster 可以在工作人员之间随机分配它们。因此,尽管node.js 通常是单线程的,但可以创建一个并行处理数据的工作人员集群。