我正在通过"功能性Javascript研讨会"通过Nodeschool。其中一个练习名为“阻止事件循环”#34;我很难理解它。通过以前的练习,我确保真正尝试理解解决方案,这样如果我不得不重做问题,我会理解如何解决它(而不是第一次破解它)。但这个概念真的让我很难受。
修改样板中提供的递归重复函数,例如 它不会阻止事件循环(即计时器和IO处理程序可以 火)。这必然要求重复是异步的。
超时在100毫秒后排队等待,这将打印出来 测试结果并退出过程。重复应该释放 控制事件循环以允许超时在所有操作完成之前中断。
尝试在超时发生之前执行尽可能多的操作!
样板
function repeat(operation, num) {
// modify this so it can be interrupted
if (num <= 0) return
operation()
return repeat(operation, --num)
}
module.exports = repeat
解决方案
function repeat(operation, num) {
if (num <= 0) return
operation()
// release control every 10 or so
// iterations.
// 10 is arbitrary.
if (num % 10 === 0) {
setTimeout(function() {
repeat(operation, --num)
})
} else {
repeat(operation, --num)
}
}
module.exports = repeat
我试图更好地理解setTimeout,我有点理解它是如何工作的。但我不明白问题本身的一些语言和概念:
修改样板中提供的递归重复函数, 这样它不会阻止事件循环(即计时器和IO处理程序可以触发)。这必然需要重复 异步。
我不明白使每10次重复异步的解决方案如何阻止重复阻止事件循环。我假设事件循环和事件队列是一样的东西?例如,点击进入事件队列,而javascript代码通过其代码同步运行,直到执行堆栈为空,然后查看队列。如何使每10次重复异步防止队列被阻止 - 我理解&#34;被阻止&#34;是队列中的项被阻塞,直到堆栈为空,此时javascript查看队列中的内容。所以,让我们说重复10,20,30等,这段代码使得那些重复异步,但它还没有继续通过所有的nums直到它达到零,此时堆栈现在是空的,在javascript看之前队列?那么这个解决方案如何解决阻塞问题呢?
接下来,问题涉及&#34;释放控制&#34;。不知道这意味着什么。什么是控制,它是如何发布的以及它发布的内容是什么?
在此之后,问题显示&#34;允许超时在所有操作完成之前中断。&#34;中断是否意味着基本上每10次重复都被中断(在同步代码结束之前不允许完成)?
最后,在超时之前尝试执行尽可能多的操作的最后挑战......我也不知道这对解决方案有何影响。 setTimeout似乎没有设定的持续时间。
答案 0 :(得分:6)
消息队列(您将其称为事件队列)是要处理的messages
的列表
事件循环将这些消息逐个处理完成
您发布的重复功能的阻止版本将是
function repeat(operation, num) {
if (num <= 0) return
operation()
repeat(operation, --num)
}
你可以看到这个递归调用自己直到num&lt; = 0,所以这不会完成,直到num&lt; = 0,因此事件循环不会处理新的消息,直到完成
将此与非阻止版本
进行对比function repeat(operation, num) {
if (num <= 0) return
operation()
// release control every 10 or so
// iterations.
// 10 is arbitrary.
if (num % 10 === 0) {
setTimeout(function() {
repeat(operation, --num)
})
} else {
repeat(operation, --num)
}
}
每10次迭代,而不是递归调用repeat,此函数将(通过setTimeout)下一次调用重复到消息队列的 end ,并且不执行任何其他操作(因此完成) )
这允许事件循环处理在setTimeout调用之前的10次迭代重复期间放置在消息队列中的任何和所有消息,并且只有当这些消息处理完成后才会执行setTimeout中的回调,这将是重复函数的下一次迭代