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

Ray*_*nos 20 javascript blocking node.js eventemitter

我可以很容易地在Node.js中编写非阻塞I/O. 这就是整个库的设置.

但任何完成的计算都是阻塞的.通过事件发射器传递的任何消息都是阻塞的.

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

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
Run Code Online (Sandbox Code Playgroud)

除了包含调用之外nextTick,如何使代码无阻塞?

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

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

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

一种选择是等待WebWorker子流程API完成.

Ric*_*asi 9

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

如果您使用逐步拆分处理process.nextTick,就像setTimeout(fn, 0)在客户端一样,以避免阻止UI,您可以在更长的时间跨度上分散工作负载,为其他功能提供运行空间.

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

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

  • Javascript仍然是单线程的,无论放置什么,你的函数都会"阻塞"._other tasks_也将阻止,你只需要切换他们的订单.**如果**你分步处理你的处理,比如它是客户端完成以避免阻止UI,你可以在更长的时间内传播相同数量的工作 - 那么你可能会获得更好的并发性,但作为交换响应时间更长.这不是node.js的意思.非阻塞代码的好处来自于不等待空闲等待响应,而不是避免所有计算. (7认同)