• 你不知道的Event Loop


    没有特别的幸运,那么就特别的努力!!!

    Eventloop的作用

    Eventloop解决javaScript单线程运行时不会阻塞的一种机制

    Eventloop事件循环

    事件队列在同步完成后,首先执行nextTick,等nextTick执行完成后,会先执行micro task,等micro task队列空了之后,才会执行macro task。(如果中间添加了micro task加入micro task队列,会继续去执行micro task队列,然后再回到macro task队列)

    简讲

    主线程(宏任务) => 微任务 => 宏任务 => 主线程

    在这里插入图片描述
    栈(zhan) —— 后进先出
    一种挤压式,先进去的被挤压到栈底 读取时数据时从栈顶开始


    线性数据结构,二叉树方式维护

    队列 —— 先进先出
    因为队列只允许一端插入,另一端删除

    宏任务

    script全部代码、setTimeout、setInterval、setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、I/O、UI Rendering。

    微任务

    Process.nextTick(Node独有)、Promise、Object.observe(废弃)、MutationObserver

    举个例子

    简化

    async function f() {
      await p
      console.log('ok')
    }
    
    • 1
    • 2
    • 3
    • 4

    等同于

    function f() {
      return RESOLVE(p).then(() => {
        console.log('ok')
      })
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    深化

    console.log('script start')
    
    async function async1() {
      await async2()
      console.log('async1 end')
    }
    async function async2() {
      console.log('async2 end') 
    }
    async1()
    
    setTimeout(function() {
      console.log('setTimeout')
    }, 0)
    
    new Promise(resolve => {
      console.log('Promise')
      resolve()
    })
      .then(function() {
        new Promise(resolve => {
          console.log('Promise4')
          resolve()
        }).then(function() {
           console.log('Promise5') 
        })
        console.log('promise1')
      })
      .then(function() {
        console.log('promise2')
      })
    
    console.log('script end')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 首先,打印script start,调用async1()时,返回一个Promise,所以打印出来async2 end
    • 每个 await,会新产生一个promise,但这个过程本身是异步的,所以该await后面不会立即调用。
    • 继续执行同步代码,打印Promisescript end,将then函数放入微任务队列中等待执行。
    • 同步执行完成之后,检查微任务队列是否为null,然后按照先入先出规则,依次执行。
    • 回到await的位置执行返回的 Promise 的 resolve 函数,打印async1 end
    • 执行打印Promise4 (如果中间添加了micro task加入micro task队列,会继续去执行micro task队列,然后再回到macro task队列)
    • 将then函数放入微任务队列中等待执行,所以接下来打印promise1
    • 再打印Promise5
    • 然后执行打印promise5,此时then的回调函数返回undefinde,此时又有then的链式调用,又放入微任务队列中,再次打印promise2
    • 当微任务队列为空时,执行宏任务,打印setTimeout

    希望能帮助到大家,同时祝愿大家在开发旅途中愉快!!!

    拿着 不谢 请叫我“锤” !!!

  • 相关阅读:
    Linux·设备文件devfs
    数字藏品,万字长文,你想知道的大部分问题都讲清楚了从业者必看
    大数据之Spark(一)
    【日常记录】Connection reset
    Redis 如何实现数据不丢失的?
    Apipost自动化测试
    【并发编程五】c++进程通信——信号量(semaphore)
    java实现PDF 转WORD
    数据结构与算法完整版 | 超详细图解,看这一篇就够了
    【深度学习】最大熵马尔科夫、CRF、条件随机场、最大匹配法
  • 原文地址:https://blog.csdn.net/hammer1010/article/details/125899050