use*_*853 3 javascript asynchronous functional-programming
我正在通过Nodeschool进行"功能性Javascript研讨会".其中一个练习的标题是"阻止事件循环",我很难理解它.通过以前的练习,我确保真正尝试理解解决方案,这样如果我不得不重做问题,我会理解如何解决它(而不是第一次破解它).但这个概念真的很挑战我.
修改样板中提供的递归重复函数,这样它就不会阻塞事件循环(即定时器和IO处理程序可以触发).这必然要求重复是异步的.
超时排队在100毫秒后触发,这将打印测试结果并退出该过程.repeat应该释放对事件循环的控制,以允许超时在所有操作完成之前中断.
尝试在超时发生之前执行尽可能多的操作!
样板
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次重复异步防止队列被阻止 - 我对"被阻止"的理解是队列中的项被阻塞,直到堆栈为空,此时javascript会查看队列中的内容.所以,让我们说重复10,20,30等,这些代码使得那些重复异步,但它不会继续通过所有的nums直到它达到零,此时堆栈现在是空的,然后javascript查看队列?那么这个解决方案如何解决阻塞问题?
接下来,问题涉及"释放控制".不知道这意味着什么.什么是控制,它是如何发布的以及它发布的内容是什么?
紧接着之后,问题就是"在所有操作完成之前允许超时中断".中断是否意味着基本上每10次重复都会被中断(在同步代码结束之前不允许完成)?
最后,最后的挑战是在超时之前尝试执行尽可能多的操作......我也看不出这对解决方案有何影响.setTimeout似乎没有设置持续时间.
消息队列(您将其称为事件队列)是messages要处理的列表
事件循环逐个处理这些消息以完成
您发布的重复功能的阻止版本将是
function repeat(operation, num) {
    if (num <= 0) return
    operation()
    repeat(operation, --num)
}
你可以看到这个递归调用自己直到num <= 0,所以这不会完成,直到num <= 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)下一次调用重复到消息队列的末尾并且不执行任何其他操作(因此完成)
这允许事件循环处理在setTimeout调用之前的10次迭代重复期间放置在消息队列中的任何和所有消息,并且只有当这些消息处理完成后才会执行setTimeout中的回调,这将是重复函数的下一次迭代