Skip to content

一、异步进阶-Event Loop

1. event loop(事件循环/事件轮询)的机制

  • JS 是单线程运行的
  • 异步要基于回调来实现
  • event loop 就是异步回调的实现原理
  • JS 如何执行?

    • 从前到后,一行一行执行
    • 如果某一行执行报错,则停止下面代码的执行
    • 先把同步代码执行完,再执行异步
  • 执行过程 event-loop

    • 先执行同步代码
      • 把第一行代码推进调用栈,准备执行。 event-loopevent-loop
      • 执行代码后,在控制台输出;再清空调用栈。
        event-loop
      • 把第二行代码推进调用栈准备执行。
        event-loop
      • 因为定时器是是Web中定义的,所以在WebAPIs中创建一个定时器。 event-loop
      • 清空调用栈。
        event-loop
      • 最后一行代码推进调用栈中。
        event-loopevent-loop
      • 执行代码,清空调用栈。
        event-loop
    • 一旦同步代码执行完,调用栈也空了。则浏览器内核开始启动Event Loop机制,这个机制的作用是,一步一步的去做循环, 每次循环都会到CallBack Queue中去寻找有没有函数要执行。
      • 5秒钟之后,定时器把cb1推到callback queueevent-loop
      • Event Loop把调用队列中的cb1函数拿到调用栈中,准备执行。 event-loopevent-loop
      • cb1函数执行到函数体中的代码。
        event-loop
      • 函数体中代码执行完后进行清空。
        event-loop
      • cb1函数执行完后调用栈也进行清空。
        event-loop
  • 总结event loop过程:

    • 同步代码,一行一行放在Call Stack执行
    • 遇到异步,会"记录"下,等待时机(定时、网络请求)
    • 时机到了,就移动到Callback Queue
    • Call Stack为空(即同步代码执行完)Event Loop开始工作
    • 轮询查找Callback Queue,如有则移动到Call Stack执行
    • 然后继续轮询查找(像永动机一样)
  • DOM事件和event loop

    js
       console.log('Hi');
       setTimeout(function cb1() {
         console.log('cb1') // cb 即 callback
       }, 5000) 
       console.log('Bye');
    html
       <button id="btn1">提交</button>
       <script>
         console.log('Hi');
         $('#btn1').click(function (e) {
             console.log('button clicked');
         })        
         console.log('Bye')
       </script>
    • JS是单线程的
    • 异步(setTimeout、ajax等)使用回调,基于event loop
    • DOM事件也使用回调,基于event loop

Released under the MIT License.