zoukankan      html  css  js  c++  java
  • js事件的执行机制(eventloop)

    一、js的内存模型

     

    二、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)

  • 相关阅读:
    【数据结构】郝斌数据结构——笔记04
    【数据结构】郝斌数据结构——笔记03
    【数据结构】郝斌数据结构——笔记02
    【JavaScript】下拉联动回显问题
    【数据结构】郝斌数据结构——笔记01
    【JavaScript】Jquery事件绑定问题
    【Java-GUI】12 Swing07 JList
    【Java-GUI】11 Swing06 JTable
    【Java-GUI】10 Swing05 JTree
    【JavaScript】下滑线命名转驼峰命名处理
  • 原文地址:https://www.cnblogs.com/yaya-003/p/12875191.html
Copyright © 2011-2022 走看看