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

时间:2022-10-30 21:31:55

I can write non-blocking I/O in Node.js very easily. It's what the entire library is set up for.

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

But any computation done is blocking. Any message passing over event emitters are blocking.

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

For example, emitting events are resolved immediately and are thus 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

Apart from wrapping calls in nextTick, how do I make code non-blocking?

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

I want to do as little computation per cycle of the event loop as possible, so that I can serve as many clients simultaneously as possible.

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

How do I write my code in a non-blocking fashion?

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

And when I have non-blocking code, how do I scale that across multiple processes?

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

One option is waiting for the WebWorker sub-process API to be finished.

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

2 个解决方案

#1


10  

JavaScript is single-threaded. That means that regardless of events, timeouts, or delaying with nextTick, any computation done will block the whole process.

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

If you split your processing in steps using process.nextTick, like it's done with setTimeout(fn, 0) on the client-side to avoid blocking the UI, you could spread your workload over a longer time span, giving some room for other functions to run.

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

But that's a very innefective solution - the total amount of work is the same, distributed among all cycles (making each request a little slower). In practice, any kind of computation that is expected to take more than a few milliseconds should be offloaded to a different process. To maximize concurrency you should always return to the event loop as quickly as possible.

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

child_process.fork() was added to v0.5 a few days ago. It simplifies child process creation and communication - not quite the web workers API, but close, see the URL https://github.com/joyent/node/blob/master/doc/api/child_process.markdown.

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

#2


2  

There's no real multi-threading in JavaScript and that's what you need to make the call non-blocking. The only thing I can think of are web-workers: https://developer.mozilla.org/en/Using_web_workers

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

#1


10  

JavaScript is single-threaded. That means that regardless of events, timeouts, or delaying with nextTick, any computation done will block the whole process.

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

If you split your processing in steps using process.nextTick, like it's done with setTimeout(fn, 0) on the client-side to avoid blocking the UI, you could spread your workload over a longer time span, giving some room for other functions to run.

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

But that's a very innefective solution - the total amount of work is the same, distributed among all cycles (making each request a little slower). In practice, any kind of computation that is expected to take more than a few milliseconds should be offloaded to a different process. To maximize concurrency you should always return to the event loop as quickly as possible.

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

child_process.fork() was added to v0.5 a few days ago. It simplifies child process creation and communication - not quite the web workers API, but close, see the URL https://github.com/joyent/node/blob/master/doc/api/child_process.markdown.

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

#2


2  

There's no real multi-threading in JavaScript and that's what you need to make the call non-blocking. The only thing I can think of are web-workers: https://developer.mozilla.org/en/Using_web_workers

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