Node.js事件循环究竟是什么? [英] What exactly is a Node.js event loop tick?

查看:98
本文介绍了Node.js事件循环究竟是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经越来越多地进入node.js体系结构的内部,我看到的一个术语是tick,如事件循环的下一个tick或函数 nextTick()

I've been getting more into the internals of the node.js architecture, and a term I see coming up a lot is "tick" as in "next tick of the event loop" or the function nextTick().

我还没有看到什么是一个确切的滴答是什么的确切定义。基于各种文章(这样的),我已经能够将一个概念拼凑在一起,但我不确定它有多准确。

What I haven't seen is a solid definition of what exactly a "tick" is. Based on various articles (such as this one), I've been able to piece a concept together in my head, but I'm not sure how accurate it is.

我能否得到node.js事件循环的精确详细描述?

Can I get a precise and detailed description of a node.js event loop tick?

推荐答案

请记住,虽然JavaScript是单线程的,但所有节点的I / O和对本机API的调用都是异步的(使用特定于平台的机制),或者在单独的线程上运行。 (这都是通过libuv处理的。)

Remember that while JavaScript is single-threaded, all of node's I/O and calls to native APIs are either asynchronous (using platform-specific mechanisms), or run on a separate thread. (This is all handled through libuv.)

因此,当套接字上有可用数据或返回本机API函数时,我们需要一种同步方式来调用JavaScript函数对刚刚发生的特定事件感兴趣。

So when there's data available on a socket or a native API function has returned, we need a synchronized way to invoke the JavaScript function that is interested in the particular event that just happened.

从发生原生事件的线程调用JS函数是不安全的,原因与你原因相同d遇到常规的多线程应用程序–竞争条件,非原子内存访问等等。

It's not safe to just call the JS function from the thread where the native event happened for the same reasons that you'd encounter in a regular multi-threaded application – race conditions, non-atomic memory access, and so forth.

所以我们所做的就是以线程安全的方式将事件放在队列中。在过度简化的伪代码中,类似于:

So what we do is place the event on a queue in a thread-safe manner. In oversimplified psuedocode, something like:

lock (queue) {
    queue.push(event);
}

然后,返回主JavaScript 线程(但在C方面,我们做了类似的事情:

Then, back on the main JavaScript thread (but on the C side of things), we do something like:

while (true) {
    // this is the beginning of a tick

    lock (queue) {
        var tickEvents = copy(queue); // copy the current queue items into thread-local memory
        queue.empty(); // ..and empty out the shared queue
    }

    for (var i = 0; i < tickEvents.length; i++) {
        InvokeJSFunction(tickEvents[i]);
    }

    // this the end of the tick
}

while(true)(节点的源代码中实际上不存在;这纯粹是说明性的)代表事件循环。 的内部为队列中的每个事件调用JS函数。

The while (true) (which doesn't actually exist in node's source code; this is purely illustrative) represents the event loop. The inner for invokes the JS function for each event that was on the queue.

这是一个勾号:同步调用与任何外部事件关联的零个或多个回调函数。一旦队列清空并且最后一个函数返回,则勾选结束。我们回到开头(下一个刻度)并检查在JavaScript运行时从其他线程添加到队列的事件

This is a tick: the synchronous invocation of zero or more callback functions associated with any external events. Once the queue is emptied out and the last function returns, the tick is over. We go back to the beginning (the next tick) and check for events that were added to the queue from other threads while our JavaScript was running.

什么可以添加到队列?


  • process.nextTick

  • setTimeout / setInterval

  • I / O(来自 fs net 等等)

  • crypto 处理器密集型函数,如加密流,pbkdf2和PRNG(实际上是......的一个例子)

  • 使用 libuv工作队列进行同步C / C ++库调用的任何本机模块看起来异步

  • process.nextTick
  • setTimeout/setInterval
  • I/O (stuff from fs, net, and so forth)
  • crypto's processor-intensive functions like crypto streams, pbkdf2, and the PRNG (which are actually an example of...)
  • any native modules that use the libuv work queue to make synchronous C/C++ library calls look asynchronous

这篇关于Node.js事件循环究竟是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆