首页 > Web开发 > 详细

js事件的执行机制(eventloop)

时间:2020-05-12 12:19:09      阅读:58      评论:0      收藏:0      [点我收藏+]

一、js代码执行机制:

  • 所有同步任务都在主线程上的栈中执行。

  • 主线程之外,还存在一个"任务队列"(task queue)只要异步任务有了运行结果,就在"任务队列"之中放置一个事件

  • 一旦"栈"中的所有同步任务执行完毕,系统就会读取"任务队列",选择出需要首先执行的任务(由浏览器决定,并不按序)。

二、宏任务与微任务:

  1. MacroTask(宏观Task) setTimeout, setInterval, , requestAnimationFrame(请求动画), I/O

  2. MicroTask(微观任务) process.nextTick, Promise, Object.observe, MutationObserver

  3. 先同步 再取出第一个宏任务执行 所有的相关微任务总会在下一个宏任务之前全部执行完毕 如果遇见 就 先微后宏

 

案例一:(在主线程上添加宏任务)

    console.log(1)
    setTimeout(function () {
      console.log(2);
    },0)
    console.log(3)  //1 3 2

先看代码:一个打印,一个定时器,一个打印

因为定时器是异步操作,又是宏任务,所以先执行第一个打印,接着将setTimeout放入宏任务队列,接着执行第二个打印再执行宏任务队列中的setTimeout

案例二:(在主线程上添加微任务)

   console.log(1)
    new Promise(function(resolve,reject){
        console.log(2)
        resolve()
    }).then(function(){
      console.log(3)
    })
    console.log(4)  //1 2 4 3

先看代码:一个打印,一个new promise,一个promise.then,一个打印

因为new promise会立即执行,promise.then是异步操作且是微任务

所以,先执行第一个打印,执行new Promise将promise.then放入微任务队列接着执行第二个打印,再执行微任务队列中的promise.then

案例三:(红任务中创建微任务)

   console.log(1);
    
    setTimeout(function () {
      console.log(2);
      new Promise(function (resolve) {
        console.log(3);
        resolve();
      }).then(function () {
        console.log(4)
      })
    },0)
  
    new Promise(function (resolve) {
      console.log(5);
      resolve();
    }).then(function () {
      console.log(6)
    })

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

先看代码:一个打印,第一个定时器,一个new promise,一个promise.then,第二个定时器,一个打印

定时器是异步操作,又是宏任务,promise.then是异步操作且是微任务

所以,先执行第一个打印(1),将第一个定时器放入宏任务队列,执行new Promise(5),将promise.then放入微任务队列,将第二个定时器放入宏任务队列,执行打印(11);

主线程上的代码执行完毕后,看是否有微任务?此时:微任务队列中有一个promise.then,执行它(6);微任务执行完毕看宏任务队列;

此时宏任务队列中两个定时器,延时都是0秒,所以按顺序执行就ok,先执行第一个定时器

第一个定时器中:一个打印,一个mew promise,一个promise.then(微任务);(宏任务中包含微任务,一定要将宏任务中的微任务执行完,再去执行下一个宏任务)

      先执行打印(2),再执行new promise(3),再执行promise.then(4);第一个宏任务执行完,执行第二个宏任务(第二个定时器)

第二个定时器中:一个打印,一个new promise,一个promise.then(微任务),一个打印

      先执行第一个打印(7),再执行new promise(8),再执行第二个打印(10),在执行promise.then(9) 

案例四:(微任务中创建宏任务)

 

   new Promise((resolve) => {
      console.log("1")
      resolve()
    }).then(() => {
      console.log("2")
      setTimeout(() => {
        console.log("3")
      },0)
    })
    setTimeout(() => {
      console.log("4")
    },1000)
    console.log("5")  //1 5 2 3 4 

 

先看代码:一个new promise,(一个then,一个定时器(0秒)),一个定时器(1秒),一个打印 微任务中有宏任务,则将宏任务放入宏任务队列任务中

先执行new promise(1),再将promise.then放入微任务队列,将定时器放入宏任务队列(0秒),将定时器放入宏任务队列(1秒),执行打印(5)

接着看微任务队列,执行promise.then(2);微任务队列中都执行完再看宏任务队列

宏任务队列中两个定时器,一个延时0秒,一个延时1秒,所以先执行延时0秒的那个

第一个定时器:执行(3);

第二个定时器:执行(4)

 

js事件的执行机制(eventloop)

原文:https://www.cnblogs.com/yaya-003/p/12875191.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!