//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);
Run Code Online (Sandbox Code Playgroud)
我的回调有一个 for 循环,它可能很长(有时 results.length = 100)。
我写了阻塞代码吗?如果是,我怎样才能让它不阻塞?
长话短说,答案是肯定的,它是阻塞。您在此循环运行时收到的任何请求都将排队。使用子进程解锁您的父代码。它要求你的机器是多核的(不是为了产生一个进程而是为了高效)。
长长的故事:
JavaScript(因此 Node)是单线程的。在这个问题的上下文中它意味着什么 - 当你的循环运行时,不能调用其他函数。解除阻塞的唯一方法是使用子进程。你有两种选择,每种都有自己的优势和缺点。
第一个选项非常简单,需要您将服务器包装在集群中http://nodejs.org/api/cluster.html 然而,您可能会“阻止”整个集群,并在每个节点进程中运行此循环。
第二种选择实施起来更复杂,需要更多的资源。但是当你必须做一些非常繁重和/或可能会导致内存泄漏的事情时,这真是太棒了。这允许你做的是创建一个单独的 Node 进程(这将需要一些 RAM 并需要一些毫秒才能启动,所以你不能产生数百万个这样的人),向它传递一些参数并等待结果到来。您的父进程将能够为即将到来的请求提供服务。但是不要忘记在完成后杀死子进程。 http://nodejs.org/api/child_process.html
无论您选择什么,请注意您仍然在同一台机器上运行,您遇到的下一个瓶颈是您的机器资源。无论如何运行一些基准测试。迭代一百多个项目并不会产生一个孩子那么重,但是如果你迭代数千个或更多?...
ps 反向循环运行得更快:
for (var i = results.length; i > 0; i--) {
//Do something
};
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5178 次 |
| 最近记录: |