cod*_*boy 15 javascript node.js
以下示例在Node.js书中给出:
var open = false;
setTimeout(function() {
open = true
}, 1000)
while (!open) {
console.log('wait');
}
console.log('open sesame');
Run Code Online (Sandbox Code Playgroud)
作者解释说明while循环阻止执行的原因:
Node永远不会执行超时回调,因为事件循环停留在第7行的while循环中,永远不会让它有机会处理超时事件!
但是,作者没有解释为什么会在事件循环的上下文中发生这种情况或者真正发生在幕后的事情.
有人可以详细说明吗?节点为什么会卡住?如何更改上面的代码,同时保留while控制结构,以便不阻止事件循环,并且代码将按照人们可能合理预期的方式运行; 等待将在setTimeout火灾前记录仅1秒,然后在记录"打开芝麻"后退出该过程.
关于IO和事件循环和回调这个问题的答案等通用解释并没有真正帮助我理解这一点.我希望直接引用上述代码的答案会有所帮助.
jfr*_*d00 23
这真的很简单.在内部,node.js由这种类型的循环组成:
如果在某些时候,事件队列中没有任何内容,则进入睡眠状态,直到事件队列中放置了某些内容.
因此,如果一个Javascript位于while()循环中,那么该任务没有完成,并且按照上述顺序,在完成前一个任务之前,不会从事件队列中挑选出任何新内容.因此,一个非常长或永远运行的while()循环只是粗糙的工作.因为Javascript一次只运行一个任务(JS执行单线程),如果那个任务在while循环中旋转,那么其他任何东西都无法执行.
这是一个可能有助于解释它的简单示例:
var done = false;
// set a timer for 1 second from now to set done to true
setTimeout(function() {
done = true;
}, 1000);
// spin wait for the done value to change
while (!done) { /* do nothing */}
console.log("finally, the done value changed!");
Run Code Online (Sandbox Code Playgroud)
有些人可能逻辑上认为while循环将旋转直到计时器触发,然后计时器将更改doneto 的值,true然后while循环将完成,并且console.log()最后将执行.那不会发生什么.这实际上是一个无限循环,并且console.log()永远不会执行该语句.
问题是,一旦你进入while()循环中的旋转等待,没有其他Javascript可以执行.因此,想要更改变量值的计时器done无法执行.因此,while循环条件永远不会改变,因此它是一个无限循环.
这是JS引擎内部发生的事情:
done 变量初始化为 falsesetTimeout() 从现在起安排计时器事件1秒钟done变量永远不会改变.因为它继续旋转,JS引擎永远不会完成这个执行线程,永远不会从事件队列中提取下一个项目.这是一个很好的问题,但我找到了解决方法!
var sleep = require('system-sleep')
var done = false
setTimeout(function() {
done = true
}, 1000)
while (!done) {
sleep(100)
console.log('sleeping')
}
console.log('finally, the done value changed!')
Run Code Online (Sandbox Code Playgroud)
我认为它有效,因为system-sleep不是旋转等待。
| 归档时间: |
|
| 查看次数: |
10077 次 |
| 最近记录: |