zoukankan      html  css  js  c++  java
  • JS小结之事件循环

    JavaScript的单线程意思是JS引擎在执行和解释JS代码的时候,都是在一个线程里完成的,而这个线程也就是所谓的“主线程”,但是实际上在处理其他的一些特殊操作的时候,是会为其开辟新的线程来专门执行,比如:

    • 处理Ajax请求
    • 处理DOM事件
    • 定时器
    • 文件的读写
      等等,这些也就是我们所说的“异步”操作。
      当代码运行到它们,我们会将他们要在这件事情完成后执行的代码注册,到达时间点了,再去触发这些注册函数。
      但我们何时才能知道应该选择哪一个任务去做?这就是JavaScript中的事件循环模型所规定的机制。

    机制介绍

    JavaScript执行引擎的主线程在运行时产生一个堆和一个栈。
    程序代码依次进入栈中(先进后出)。
    当调用setTimeout()方法,浏览器相应的内核模块开始进行监听发生条件的触发。
    如果达到了触发条件,方法就会加入回调任务队列。
    引擎栈的代码执行完毕的时候,主线程才会去读取任务队列,依次执行满足触发条件的回调函数。

    例子1

    console.log('start');  // 入栈,执行出栈
    
    //Timer1    入栈,出栈把回调函数放入timer模块
    setTimeout(function(){
        console.log('hello');
    },200);
    
    //Timer2   同上
    setTimeout(function(){
        console.log('world');
    },100);
    
    console.log('end'); // 入栈,执行出栈
    // 执行栈已经被清空,这时候Timer模块检查异步代码
    // 如果触发条件达成,回调函数加入任务队列
    // Timer2早于Timer1被加入到任务队列中,主线程空闲,于是检查任务队列是否有可以执行的,以此循环检查。
    

    例子2

    console.log(1);
    //Time1
    setTimeout(function(){
        console.log(2);
    },300);
    //Time2
    setTimeout(function(){
        console.log(3)
    },400);
    
    // for循环所需时间长,此时前面两个回调函数都已在任务队列
    for (var i = 0;i<10000;i++) {
        console.log(4);
    }
    //Time3
    setTimeout(function(){
        console.log(5);
    },100);
    

    宏队列与微队列

    任务队列分为两类,一种是宏队列,一种是微队列。
    宏队列在每次事件循环中只会提取执行一个,
    微队列会把队列中所有的任务都提取出来执行再进行下一次的提取。
    并且微队列中的任务要比宏队列中的任务优先检查执行。

    举个例子

    // (回调)加入微队列
    process.nextTick(() => {
      console.log('nextTick')
    })
    
    // 加入宏队列
    setTimeout(() => {
      console.log('setTimeout1')
    })
    
    // then回调加入微队列
    Promise.resolve()
      .then(() => {
        console.log('then')
      })
    
    // 加入宏队列
    setTimeout(() => {
      console.log('setTimeout2')
    })
    
    // 主线程,先执行
    console.log('end')
    

    在输出end后,主栈为空。
    就检查微队列是不是为空,有两个已经加入,全部执行。
    再看宏队列,虽然有两个,但是它这次只执行一个。
    再进行第二轮循环,只有宏队列还剩下一个任务。
    所以结果是:

    end nextTick then setTimeout1 setTimeout2
    

    P.S:这个部分我原来在Promise相关的小结上也小小总结过,这次联系起来更加深入的理解。

    宏队列代表

    • setTimeout
    • setInterval
    • setImmediate
    • requestAnimationFrame
    • I/O
    • UI rendering

    微队列代表

    • process.nextTick
    • Promises
    • Object.observe
    • MutationObserver
  • 相关阅读:
    vba Application.OnTime 定时器
    Linq to XML
    Jquery Ajax+.ashx Json数据格式
    存储过程
    Jquery Ajax +.ashx XML数据格式
    原生态JS  图片滚动
    Standup Timer的MVC模式及项目结构分析
    android的Handler
    Microsoft Office Sharepoint Server 2007数据库日志文件逐渐增大处理笔记
    windows 网络编程学习Winsock API
  • 原文地址:https://www.cnblogs.com/rimochiko/p/12640986.html
Copyright © 2011-2022 走看看