如何在Node.js中编写非阻塞代码?

时间:2011-04-14 21:56:02

标签: javascript node.js blocking eventemitter

我可以非常轻松地在I/O中编写非阻塞Node.js 。这就是为整个库设置的目的。

但是所做的任何计算都是阻塞的。通过event emitters are blocking传递的任何邮件。

例如,发射事件会立即解决,因此会阻塞:

var e = new process.EventEmitter;
e.on("foo", function() {
    console.log("event");
});
process.nextTick(function() {
    console.log("next tick");
});
setTimeout(function() {
    console.log("timeout");
}, 0);
e.emit("foo");

> event
> next tick
> timeout

除了在nextTick中打包电话外,如何使代码无阻塞?

我希望尽可能少地在事件循环的每个周期进行计算,这样我就可以同时为多个客户端提供服务。

如何以非阻塞方式编写代码?

当我有非阻塞代码时,如何在多个进程中进行扩展?

一个选项是等待WebWorker子流程API完成。

2 个答案:

答案 0 :(得分:9)

JavaScript是单线程的。这意味着无论事件,超时或延迟使用nextTick,任何完成的计算都将阻止整个过程。

如果您使用process.nextTick分步处理,就像在客户端使用setTimeout(fn, 0)一样,以避免阻止用户界面,您可以在更长的时间内分散工作量,其他功能运行的空间。

但这是一个非常无用的解决方案 - 总工作量是相同的,分布在所有周期中(使每个请求稍慢)。在实践中,任何预计需要花费超过几毫秒的计算都应该卸载到不同的进程中。为了最大化并发性,您应该始终尽快返回事件循环

几天前,

child_process.fork()被添加到v0.5。它简化了子进程的创建和通信 - 不仅仅是Web worker API,而是关闭,请参阅URL https://github.com/joyent/node/blob/master/doc/api/child_process.markdown

答案 1 :(得分:1)

JavaScript中没有真正的多线程,而这就是使呼叫无阻塞所需要的。我唯一能想到的是网络工作者:https://developer.mozilla.org/en/Using_web_workers