21

我可以非常轻松地在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

除了包装调用nextTick,我如何使代码非阻塞?

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

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

当我有非阻塞代码时,如何跨多个进程扩展它?

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

4

2 回答 2

9

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

如果您使用 分步处理process.nextTick,就像setTimeout(fn, 0)在客户端完成以避免阻塞 UI 一样,您可以将工作负载分散在更长的时间范围内,从而为其他功能的运行留出一些空间。

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

child_process.fork()几天前被添加到v0.5。它简化了子进程的创建和通信——不完全是网络工作者 API,而是关闭,请参阅URL https://github.com/joyent/node/blob/master/doc/api/child_process.markdown

于 2011-04-14T23:22:44.447 回答
1

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

于 2011-04-14T22:10:39.597 回答