浅尝event Loop 事件循环

event Loop
简介

Event Loop即事件循环,也就是我们经常使用异步的原理。
是指浏览器或Node的一种解决javaScript单线程运行时阻塞的一种解决方案机制。

众所周知我们JavaScript的执行是单线程的,代码是从上往下依次执行的,只有当上一个任务完成之后才会继续完成下一个任务,如果前一个任务耗时很长,后一个任务就不得不一直等着。于是我们的执行代码被分为同步任务与异步任务

  1. 同步任务
    在主线程上排队执行的任务,只有前一个任务执行完毕,才能执行后一个任务;

  2. 异步任务
    不进入主线程、而进入"任务队列"(task queue)的任务,只有"任务队列"通知主线程,某个异步任务触发一定条件或可以执行了,该任务才会进入主线程执行。


  • 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
  • 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
  • 一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
  • 主线程不断重复上面的第三步。

主线程从任务队列中读取事件,这个过程是不断循环的,所以整个的运行机制称为event loop


了解异步任务

异步任务之间存在执行优先级的区别的。不同的异步任务会被分为两类,微任务和宏任务;先执行宏任务,再执行微任务

macro-task(宏任务)

script全部代码、setTimeout、setInterval、setImmediate(浏览器暂时不支持,只有IE10支持,具体可见MDN)、I/O、UI Rendering
以上的情况会产生宏任务

MicroTask(微任务)

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

image


上代码进行理解


    console.log(1);
    setTimeout(() => {
      console.log(2);
    })
    new Promise((resolve) => {
      console.log(3)
      resolve()
    }).then(() => {
      setTimeout(() => {
        console.log(4);
      })
    }).then(() => {
      console.log(5)
    })
    console.log(6)
    setTimeout(() => {
      console.log(7)
      new Promise(resolve => {
        console.log(8)
        setTimeout(() => {
          console.log(9)
        })
        resolve()
      }).then(() => {
        console.log(10)
      })
    }, 0)
    console.log(11)

执行结果是 1、3、6、11、5、2 、7 、8 、10 、4 、9

进行异步机制的分析
image
注意的:promise有个小点要注意的是 promise内部执行是同步的,then...等api是异步的
先执行首层的宏任务 微任务:1 3 6 11 5
再执行第二层的宏任务 微任务:2 7 8 10
再执行第三层的宏任务 微任务:4 9

按照先宏任务再微任务的顺序,彼此之间的宏任务按照顺序来执行;
微任务可以插队,而宏任务不行

posted @ 2022-07-27 13:39  xiao旭  阅读(57)  评论(0编辑  收藏  举报