阻止事件循环 [英] Blocking Event Loop

查看:193
本文介绍了阻止事件循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我要通过功能的Javascript研讨会,通过Nodeschool。其中一个练习的题目是阻塞事件循环和我有困难的理解它。与过去​​的练习,我已经确定要真正试图了解解决方案,因此,如果我不得不重做的问题,我会知道如何解决这个问题(而不是黑客走在它的第一次)。但是,这个概念是真正具有挑战性我。


  

修改样板提供递归复读功能,例如
  它不阻止事件循环(即定时器和IO处理器可以
  火)。这必然要求重复是异步的。


  
  

一个超时排队后100毫秒火,这将打印
  测试和结果退出该过程。重复应该释放
  事件循环的控制,允许超时完成所有的操作前中断。


  
  

尝试执行尽可能多的操作,你可以超时闪光之前!


  
  

样板


 功能重复(操作,NUM){
  //修改此,因此它可以被中断
  如果(NUM< = 0)返回
  操作()
  回重复(操作,--num)
}module.exports =重复


  

解决方案


 功能重复(操作,NUM){
        如果(NUM< = 0)返回        操作()        //释放控制每10左右
        //迭代。
        // 10是任意的。
        如果(NUM%10 === 0){
          的setTimeout(函数(){
            重复(操作,--num)
          })
        }其他{
          重复(操作,--num)
        }
      }module.exports =重复

我试图理解的setTimeout更好,我有点明白它是如何工作的。但我有些不明白,语言和概念在问题本身:


  

修改样板提供递归复读功能,
  这样,它不会阻止事件循环(即定时器和IO处理程序可以开火)。这必然要求重复是
  异步的。


我不知道如何解决,这使得每10个重复异步,prevents堵塞事件循环重复。我假设事件循环和事件队列都喜欢一样的东西?例如点击均放置在事件队列,而JavaScript的code通过其code同步运行,直到执行堆栈是空的,然后队列得到看着。如何使每10重复异步prevent被阻塞队列 - 我的被封杀的理解是,在队列中的项目被阻塞,直到堆栈为空,此时的javascript看什么是队列。所以让我们在重复10,20,30等说,这code使这些重复异步,但不会仍然可以通过所有NUMS继续,直至降为零,此时堆栈现在是空的,JavaScript的容貌之前在队列?那么,如何解决这个解决阻断像问题问?

接下来的问题是指释放控制。不知道这意味着什么。什么是控制和它是如何发布的又是什么呢发布?

紧接着,这个问题说允许超时之前,所有操作完全中断。是否中断意味着基本上每10个重复中断(不允许完成,直到同步code结尾)?

最后,在最后的挑战,试图执行许多操作作为一个可以前的超时火灾...我也看不出如何适用于解决方案。该setTimeout的甚至不似乎有一个设定时间。


解决方案

消息队列(你是指它作为事件队列)为的邮件列表是处理

事件循环处理这些消息一个接一个的完成

您发布将是重复功能的阻断版

 功能重复(操作,NUM){
    如果(NUM< = 0)返回    操作()    重复(操作,--num)
}

您可以看到,这个递归调用自身,直到NUM< = 0,所以这不会完成,直到NUM< = 0,因此没有新的消息将通过事件循环处理,直到它完成

与非阻塞版本对比这

 功能重复(操作,NUM){
    如果(NUM< = 0)返回    操作()    //释放控制每10左右
    //迭代。
    // 10是任意的。
    如果(NUM%10 === 0){
        的setTimeout(函数(){
            重复(操作,--num)
        })
    }其他{
        重复(操作,--num)
    }
}

每10次迭代,而不是递归调用重复,这个函数的地方(凭借的setTimeout)的下一次调用重复到消息队列的结束并没有别的(因此完成)

这使得事件循环过程中,setTimeout调用前10次迭代重复被放置在消息队列的任何及所有信息,而且只有一次的消息已经被处理完毕将在setTimeout的回调执行,这将是重复功能的下一次迭代

I'm going through the "Functional Javascript Workshop" through Nodeschool. One of the exercises is titled "Blocking Event Loop" and I am having difficulty understanding it. With past exercises, I have made sure to really try to understand the solution so that if I were to have to redo the problem, I would understand how to solve it (as opposed to hacking away at it the first time). But this concept is really challenging me.

Modify the recursive repeat function provided in the boilerplate, such that it does not block the event loop (i.e. Timers and IO handlers can fire). This necessarily requires repeat to be asynchronous.

A timeout is queued to fire after 100 milliseconds, which will print the results of the test and exit the process. repeat should release control of the event loop to allow the timeout to interrupt before all the operations complete.

Try to perform as many operations as you can before the timeout fires!

Boilerplate

function repeat(operation, num) {
  // modify this so it can be interrupted
  if (num <= 0) return
  operation()
  return repeat(operation, --num)
}

module.exports = repeat

Solution

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

I have sought to understand setTimeout better and I somewhat understand how it works. But I do not understand some of the language and concepts in the question itself:

Modify the recursive repeat function provided in the boilerplate, such that it does not block the event loop (i.e. Timers and IO handlers can fire). This necessarily requires repeat to be asynchronous.

I don't understand how the solution, which makes every 10th repeat async, prevents repeat from blocking the event loop. I'm assuming the event loop and event queue are like the same things? For instance clicks get placed on the event queue while the javascript code is running synchronously through its code until the execution stack is empty and then the queue gets looked at. How does making every 10th repeat async prevent the queue from being blocked -- my understanding of "being blocked" is that items in the queue are blocked until the stack is empty, at which point javascript looks at what is in the queue. So lets say at repeat 10, 20, 30 etc, this code makes those repeats async, but doesn't it still continue through all the nums until it hits zero, at which point the stack is now empty, before javascript looks at the queue? So how does this solution resolve that blocking like the question asks?

Next, the question refers to "releasing control". No clue what that means. What is control and how is it released and what is it released to?

Immediately after that the question says "allow the timeout to interrupt before all the operations complete." Does interruption mean that basically every 10th repeat is interrupted (not allowed to complete until the synchronous code ends)?

Finally, the challenge at the end to try and perform as many operations as one can before the timeout fires... I also don't see how that applies to the solution. The setTimeout doesn't even seem to have a set duration.

解决方案

The message queue (you refer to it as the event queue) is a list of messages to be processed

The event loop processes these messages one by one to completion

The blocking version of the repeat function you posted would be

function repeat(operation, num) {
    if (num <= 0) return

    operation()

    repeat(operation, --num)
}

You can see that this recursively calls itself until num <= 0, so this wont complete until num <= 0, therefore no new messages will be processed by the event loop until this finishes

Contrast this with the non blocking version

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)
    }
}

every 10 iterations, rather than recursively calling repeat, this function places (by virtue of the setTimeout) the next call to repeat to the end of the message queue and does nothing else (therefore is completed)

this allows the event loop to process any and all messages that were placed on the message queue during the 10 iterations of repeat before the setTimeout call, and only once those messages have been processed to completion will the callback in setTimeout be executed, which will be the next iteration of the repeat function

这篇关于阻止事件循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆