zoukankan      html  css  js  c++  java
  • 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

     参考的相关博客   相关博客 

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

     之后会继续补充 

  • 相关阅读:
    利用dockerfile定制镜像
    发布Docker 镜像到dockerhub
    Docker 停止容器
    133. Clone Graph
    132. Palindrome Partitioning II
    131. Palindrome Partitioning
    130. Surrounded Regions
    129. Sum Root to Leaf Numbers
    128. Longest Consecutive Sequence
    127. Word Ladder
  • 原文地址:https://www.cnblogs.com/GoTing/p/13503377.html
Copyright © 2011-2022 走看看