我已经越来越多地进入node.js体系结构的内部,我看到的一个术语是“tick”,如“事件循环的下一个tick”或函数nextTick()
我没有看到的是对什么是“滴答”的确切定义。基于各种文章(such as this one),我已经能够将一个概念拼凑在一起,但我不确定它是多么准确。
我能获得node.js事件循环的精确详细描述吗?
答案 0 :(得分:121)
请记住,虽然JavaScript是单线程的,但所有节点的I / O和对本机API的调用都是异步的(使用特定于平台的机制),或者在单独的线程上运行。 (这都是通过libuv处理的。)
因此,当套接字或本机API函数返回时,我们需要一种同步方式来调用对刚刚发生的特定事件感兴趣的JavaScript函数。
从发生本机事件的线程调用JS函数是不安全的,原因与您在常规多线程应用程序中遇到的原因相同 - 竞争条件,非原子内存访问等等。
所以我们所做的是以线程安全的方式将事件放在队列中。在过度简化的伪代码中,类似于:
lock (queue) {
queue.push(event);
}
然后,回到主要的线程(但在C方面),我们做了类似的事情:
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)
(实际上不存在于节点的源代码中;这纯粹是说明性的)代表事件循环。内部for
为队列中的每个事件调用JS函数。
这是一个勾号:同步调用与任何外部事件关联的零个或多个回调函数。一旦队列清空并且最后一个函数返回,则勾选结束。我们回到开头(下一个tick)并检查在我们的JavaScript运行时从其他线程添加到队列的事件。
什么可以添加到队列?
process.nextTick
setTimeout
/ setInterval
fs
,net
的内容,等等)crypto
处理器密集型函数,如加密流,pbkdf2和PRNG(实际上是......的一个例子)答案 1 :(得分:5)
对JavaScript新手来说更简单的答案:
首先要理解的是JavaScript是一个单线程环境&#34;。这是指JavaScript一次一个地执行代码块的行为#34;事件循环&#34;在一个线程上。下面是从Kyle Simpson的书ydkJS中获取的事件循环的基本实现,然后是一个解释:
good
第一个while循环模拟事件循环。 tick是从&#34;事件循环队列中排除事件&#34;以及所述事件的执行。
请参阅&#39; Josh3796&#39;有关事件的出列和执行中发生的事情的更详细说明。
此外,我建议您阅读Kyle Simpson的书,以了解那些有兴趣深入了解JavaScript的人。它是完全免费和开源的,可以在以下链接找到: https://github.com/getify/You-Dont-Know-JS
我引用的具体部分可以在这里找到:https://github.com/getify/You-Dont-Know-JS/blob/master/async%20%26%20performance/ch1.md#event-loop
答案 2 :(得分:1)
“tick”是指完全通过事件循环。令人困惑的是,setImmediate() 需要一个滴答来运行,而 process.nextTick() 更直接,因此这两个函数应该交换名称。
答案 3 :(得分:0)
事件循环刻度的非常简单的方法是:
节点内部机制使用它,当队列中的请求集被处理后,滴答声被启动,代表任务的完成