用于循环callback。 阻止?

//defining schemas, models, db connections, etc.. http.createServer(function (req, res) { // some irrelevant stuff.. Model.find({name : regex}).exec(function (err, results) { var localArray = []; for (var i = 0, len = results.length; i < len; ++i) { localArray.push(results[i].name); localArray.push(results[i].id); }; // is this for loop blocking? // some more irrelevant stuff.. }); }).listen(8080); 

我的callback有一个for循环,可以很长(有时results.length = 100)。

我写了封锁代码吗? 如果是的话,我怎样才能使它不被阻塞?

长话短说,答案是肯定的,这是封锁。 此循环正在运行时收到的任何请求将排队。 使用subprocess来解锁你的父代码。 它需要你的机器是多核(不是产生一个进程,而是高效)。

漫长的故事:

JavaScript(和Node因此)是单线程的。 这个问题的含义是什么 – 当你的循环运行时,没有其他的函数可以被调用。 解除阻止的唯一方法是使用subprocess。 你有两个select,每个都有自己的力量和缺点。

  1. 运行一个集群,以便当一个节点进程“被阻塞”时,您有另一个进程来处理传入的请求。
  2. 产生一个孩子的过程,为你运行一些重的东西,然后报告结果。

第一个选项非常简单,需要将服务器包装在集群中http://nodejs.org/api/cluster.html然而,在每个节点进程中运行此循环的机会是“阻塞”整个集群&#x3002;

第二种方法实施起来比较复杂,需要更多的资源。 但是,当你必须做一些非常重的和/或可能的memory leaks时,这是惊人的。 这可以让你做的是创build一个单独的节点进程(这将需要一些内存,并需要几毫秒的时间开始,所以你不能派生成百万这些家伙),传递一些参数,并等待结果来。 您的父母程序将能够提供即将到来的请求。 但是一旦完成,不要忘记杀死subprocess。 http://nodejs.org/api/child_process.html

无论您select什么,请注意,您仍在同一台机器上运行,遇到的下一个瓶颈是您的机器资源。 无论如何运行一些基准。 迭代超过一百个项目不会产生一个孩子,但如果你重复数以千计或更多?…

ps反转循环运行得更快:

 for (var i = results.length; i > 0; i--) { //Do something };