我一直在深入了解 node 的内部 struct .js架构,我经常看到的一个术语是"滴答声",如"事件循环的下一滴答声"或函数nextTick().
我还没有看到"滴答"到底是什么的确切定义.根据各种文章(such as this one篇),我已经能够在脑海中拼凑出一个概念,但我不确定它有多准确.
我能得到一个 node 的精确和详细的描述吗.js事件循环滴答?
我一直在深入了解 node 的内部 struct .js架构,我经常看到的一个术语是"滴答声",如"事件循环的下一滴答声"或函数nextTick().
我还没有看到"滴答"到底是什么的确切定义.根据各种文章(such as this one篇),我已经能够在脑海中拼凑出一个概念,但我不确定它有多准确.
我能得到一个 node 的精确和详细的描述吗.js事件循环滴答?
请记住,虽然JavaScript是单线程的,但所有 node 的I/O和对本机API的调用要么是异步的(使用特定于平台的机制),要么在单独的线程上运行.(这些都是通过libuv处理的.)
因此,当套接字上有可用数据或本机API函数返回时,我们需要一种同步方式来调用对刚刚发生的特定事件感兴趣的JavaScript函数.
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.
所以我们要做的是以线程安全的方式将事件放置在队列中.在过于简化的伪代码中,类似于:
lock (queue) {
queue.push(event);
}
然后,回到主JavaScript thread(但在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)
(实际上并不存在于node的源代码中;这纯粹是说明性的)代表event loop.内部for
为队列中的每个事件调用JS函数.
这是一个记号:与任何外部事件关联的零个或多个回调函数的同步调用.一旦队列清空,最后一个函数返回,勾号就结束了.我们回到开头(下一个勾号),判断从其他线程添加到队列中的事件.
什么东西可以添加到队列中?
process.nextTick
setTimeout
/setInterval
fs
、net
等的内容)crypto
的处理器密集型功能,如加密流、pbkdf2和PRNG(实际上是…)