我们如何阻止事件循环?
How can we block event loop?
我研究过Node.Js中的事件循环,它以异步和非阻塞的方式处理请求。有什么办法可以阻止事件循环的执行吗?
有很多方法可以阻止事件循环。有些方法只是暂时阻止它(比如使用同步文件 I/O),有些方法会永远阻止它。
例如,这将永远阻止它:
let flag = false;
setTimeout(() => {
// this callback never gets called
// because event loop is blocked
flag = true;
}, 1000);
while (!flag) {
console.log("still waiting")
}
// never get here
问题是 while()
循环一直运行到 flag
更改值。只要while循环是运行,事件循环就被阻塞了。有一个 setTimeout()
想要在 1 秒内触发,但在解释器返回到事件循环之前它实际上不能调用它的回调。但是,在 while()
循环完成之前,它不会返回到事件循环。这是一个导致无限循环的死锁,事件循环被永久阻塞。
在 while
循环完成之前,setTimeout()
无法调用其回调,并且在 setTimeout()
运行其回调之前,while
循环不会结束。死锁,无限循环。
这会在所有文件操作和所有文件处理过程中阻塞它一段时间:
setTimeout(() => {
// this doesn't get to run until all the synchronous file I/O
// finishes in the code below, even though the timer is set
// for only 10ms
console.log("finally got to run the timer callback");
}, 10);
let files = some array of files;
for (let file of files) {
let data = fs.readFileSync(file);
let lines = data.split("\n");
for (let line of lines) {
// do something
}
}
事件循环在线程上运行,因此任何阻塞线程的调用(如无限循环、同步文件操作或阻塞网络调用)都会阻塞事件循环。
你可以把事件循环想象成先进先出的回调队列,如果一个函数调用卡住了,后续的调用会等待它完成。
您还可以通过使用 setTimeout 或 setInterval 函数将新任务无限排队到末尾来阻止事件循环。
我研究过Node.Js中的事件循环,它以异步和非阻塞的方式处理请求。有什么办法可以阻止事件循环的执行吗?
有很多方法可以阻止事件循环。有些方法只是暂时阻止它(比如使用同步文件 I/O),有些方法会永远阻止它。
例如,这将永远阻止它:
let flag = false;
setTimeout(() => {
// this callback never gets called
// because event loop is blocked
flag = true;
}, 1000);
while (!flag) {
console.log("still waiting")
}
// never get here
问题是 while()
循环一直运行到 flag
更改值。只要while循环是运行,事件循环就被阻塞了。有一个 setTimeout()
想要在 1 秒内触发,但在解释器返回到事件循环之前它实际上不能调用它的回调。但是,在 while()
循环完成之前,它不会返回到事件循环。这是一个导致无限循环的死锁,事件循环被永久阻塞。
在 while
循环完成之前,setTimeout()
无法调用其回调,并且在 setTimeout()
运行其回调之前,while
循环不会结束。死锁,无限循环。
这会在所有文件操作和所有文件处理过程中阻塞它一段时间:
setTimeout(() => {
// this doesn't get to run until all the synchronous file I/O
// finishes in the code below, even though the timer is set
// for only 10ms
console.log("finally got to run the timer callback");
}, 10);
let files = some array of files;
for (let file of files) {
let data = fs.readFileSync(file);
let lines = data.split("\n");
for (let line of lines) {
// do something
}
}
事件循环在线程上运行,因此任何阻塞线程的调用(如无限循环、同步文件操作或阻塞网络调用)都会阻塞事件循环。
你可以把事件循环想象成先进先出的回调队列,如果一个函数调用卡住了,后续的调用会等待它完成。
您还可以通过使用 setTimeout 或 setInterval 函数将新任务无限排队到末尾来阻止事件循环。