哪个事件循环阶段执行正常的JavaScript代码
我是node.js的新手,对理解事件循环有点困惑。 据我所知,从https://github.com/nodejs/node/blob/master/doc/topics/event-loop-timers-and-nexttick.md ,事件循环阶段只处理setTimeout,setInterval,setImmediate ,process.nextTick,promise和一些I / Ocallback。
我的问题是,如果我有以下代码:
for(var i = 0; i <100000000; i ++);
上述代码将在哪个阶段执行?
常规的JavaScript代码,比如你的例子中的for
循环,在队列被清除之前执行。 节点将要做的第一件事就是运行你的代码,并且在你的代码完成后只会调用callback函数,超时结果,I / O结果等等。
作为一个例子,你可以试试这个代码:
fs.open('filename', 'r', () => { console.log('File opened.'); }); for (var i = 0; i < 100000000; i++); console.log('Loop complete.');
无论循环variables有多大或多小,“循环完成”将始终显示在“文件打开”之前。 这是因为只有一个线程,节点不能运行你提供给fs.open函数的callback,直到循环代码完成。
请记住,没有节点继续返回的“主”线程。 大多数长时间运行的节点程序会很快地在main.js中运行,后续的代码将全部来自callback。 初始执行的目的是定义这些callback如何以及何时发生。
在节点事件循环文档( https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick )中,以下代码作为示例给出:
const fs = require('fs'); function someAsyncOperation(callback) { // Assume this takes 95ms to complete fs.readFile('/path/to/file', callback); } const timeoutScheduled = Date.now(); setTimeout(() => { const delay = Date.now() - timeoutScheduled; console.log(`${delay}ms have passed since I was scheduled`); }, 100); // do someAsyncOperation which takes 95 ms to complete someAsyncOperation(() => { const startCallback = Date.now(); // 10ms loop while (Date.now() - startCallback < 10) { // do nothing } });
循环根据阶段不断扫描,在fs.readFile()
完成后,轮询队列是空的,所以它的callback将被添加并立即执行。 在执行定时器之前,callback会持续一个阻塞的10ms循环。 这就是延迟显示的原因: 105ms have passed since I was scheduled
毫秒,而不是你可能期望的100毫秒。
你的大部分代码都会在callback中生效,所以会在轮询阶段执行。 如果没有,就像在你的例子中那样,它会在进入任何阶段之前被执行,因为它会阻塞事件循环。
警告是由setImmediate
调度的callback,它将在下一个循环中恢复轮询阶段之前进入检查阶段。