• event loop 事件循环


    js是单线程运行,从上到下逐步执行,js有一个:主线程,还有一个回调队列。在js中,任务分为同步任务和异步任务;

    当遇到异步任务(ajax,settimeout等),会先注册异步回调函数,等异步任务执行完的时候,会把异步回调放在一个先进先出的队列里,当主线程执行完毕之后,会读取队列里的异步回调函数,这个不断重复的过程就是 event loop 事件循环。

    JS的事件循环如图所示,

    1. 在执行主线程的任务时,如果有异步任务,会进入到Event Table并注册回调函数,当指定的事情完成后,会将这个回调函数放到 callback queue 中
    2. 在主线程执行完毕之后,会去读取 callback queue中的回调函数,进入主线程执行
    3. 不断的重复这个过程,也就是常说的Event Loop(事件循环)了

    异步任务

    js的异步任务,分为宏任务跟微任务、他们之间的区别主要是执行顺序的不同。

    在js中

    微任务

    • 原生的Promise (new Promise在实例化的过程中所执行的代码都是同步进行的,而then中注册的回调才是异步执行)

    • process.nextTick 

    process.nextTick的执行优先级高于Promise

    宏任务

    • 整体代码 script
    • setTimeout 
    • setImmediate

    setTimeout的执行优先级高于 setImmediate 的

    宏任务与微任务的执行过程

    在一次事件循环中,JS会首先执行 整体代码 script,执行完后会去判断微任务队列中是否有微任务,如果有,将它们逐一执行完后在一次执行宏任务。如此流程

    大体可以这样排序

      整体代码 script  process.nextTick > Promise > setTimeout  > setImmediate 

    当遇到这种类型的题目 可以先列出4行

    宏任务

    微任务

    执行队列

    输出

    以一个题目为例

    process.nextTick(() => {
      console.log('a');
      setImmediate(() => {
        console.log('d')
      })
    })
    
    setImmediate(() => {
      console.log('b');
      process.nextTick(() => {
        console.log('c')
      })
    })
    

      答案 abcd,解析过程:

    一开始 执行 ,js代码放在宏任务 ,此时执行队列为空,微任务为空

    宏任务  js代码 

    微任务 

    执行队列   

    输出

    所以将宏任务中js代码放在执行队列中   

    宏任务  

    微任务 

    执行队列    js代码 

    输出

    然后把 nextTick放在微任务中,setImmediate放在宏任务中

    宏任务   setImmediate

    微任务 nextTick

    执行队列   

    输出   

    当微任务中有任务 则优先微任务 此刻有一个nextick 将他内部的内容进行解读 执行 console.log('a'); 优先输入 再将setImmediate 放入宏任务队列

    宏任务   setImmediate  setImmediate(console.log('d'))

    微任务 

    执行队列  console.log('a'); 

    输出  a

    执行完执行队列 后,微任务没有任务 则看宏任务setImmediate  中有一个 console.log('b');直接执行 ,然后有一个nextTick放在微任务中

    宏任务   setImmediate(console.log('d'))

    微任务  nextTick

    执行队列  console.log('b');

    输出  a  

    执行微任务中的nextTick  console.log('c')

    宏任务   setImmediate(console.log('d'))

    微任务 

    执行队列  console.log('c');

    输出  a  b c

    之后微任务没有任务 继续看宏任务中的setImmediate,输出 d

    宏任务   

    微任务 

    执行队列  console.log('d')

    输出  a  b c

    所以最后的答案是 abcd

    实际遇到的问题会比这个更加复杂 ,记住步骤 以及   整体代码 script  process.nextTick > Promise > setTimeout  > setImmediate 执行优先顺序

    注意点:

    new Promise实例化的过程中所执行的代码都是同步进行的,而then中注册的回调才是异步执行 

    setTimeout(_ => console.log(4))
    
    new Promise(resolve => {
      resolve()
      console.log(1)
    }).then(_ => {
      console.log(3)
    })
    
    console.log(2)
    

      答案是 1234

    这里有一个博客  你可以很清晰得看到 运行的顺序  十分推荐 看这个

    https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/?utm_source=html5weekly

     参考的相关博客   相关博客 

    找到了一个 博客讲的很有意思 放在这里方便以后查看 

     之后会继续补充 

  • 相关阅读:
    hadoop hbase 完全分布式
    在linux 下安装 solr 的IK中文分词
    Solr的多核配置和分布式
    vi命令
    SilverLigth的Chart不要图例(Legend)的方法
    【转载】Silverlight 应用 WCF RIA Services 在 IIS6 部署问题总结
    上下文菜单点击获取ContextMenu实例方法
    WPF中StringFormat的用法可以参照C#中string.Format的用法
    WPF的转换器中使用Brush应注意问题
    VS2010 SL4解决方案前端发现不了解决方案中WCF服务问题
  • 原文地址:https://www.cnblogs.com/GoTing/p/13503377.html
Copyright © 2020-2023  润新知