• JavaScript中的宏任务和微任务


    面试中经常会被问到什么宏任务和微任务?工作中也会出一个奇怪的问题,两行代码,一会A结果现出来,一会B结果先出来,搞得一头雾水。有些人为了懒省事,全都是用async await,亦或者写个setTimeout,也不去追究原理,能解决问题就行。接下来就对这个问题展开讨论。

    什么是宏任务和微任务?

    宏任务是由宿主(浏览器、Node)发起的,一般在JavaScript引擎空闲时执行(不知道这样说合不合理)。常见的宏任务有:setTimeoutsetIntervalAjaxDOM事件

    微任务是指在当前任务执行结束后立即执行的任务。常见的微任务有:Promiseasync/await。其中Promise本身是同步的,.then/.catch才是异步的。

    执行顺序

    首先,在JavaScript中,任务分为同步任务和异步任务,异步任务又有宏任务和微任务。同步任务在主线程中,异步任务会进入任务队列。

    同步任务 》微任务 》宏任务

    一起来看一下下面这个例子:

    console.log(1);
    setTimeout(() => {
      console.log("setTimeout");
    }, 1000);
    new Promise((resolve, reject) => {
      console.log("Promise1");
      resolve("resolve");
      console.log("Promise2");
    }).then((data) => {
      console.log(data);
    });
    console.log(2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    先区分一下都是什么任务:

    image.png

    按照上面的顺序,依次输出1Promise1Promise22resolvesetTimeout,这里值得说一下Promise本身是同步的,.then/.catch才是异步的,所以会先输出Promise1,而resolve("resolve")是告诉Promise成功了,并不阻碍进程,所以会继续输出Promise2

    可能有人会说setTimeout一秒后才执行,肯定最后输出了,再看一个例子,把setTimeout设置为0,应该会立即执行吧?:

    console.log(1);
    setTimeout(() => {
      console.log("setTimeout");
    }, 1000);
    setTimeout(() => {
      console.log("setTimeout0");
    }, 0);
    new Promise((resolve, reject) => {
      console.log("Promise1");
      resolve("resolve");
      console.log("Promise2");
    }).then((data) => {
      console.log(data);
    });
    console.log(2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    也是先分析都是什么任务,依次输出1Promise1Promise22resolvesetTimeout0setTimeout,虽然setTimeout设置为0,他也是宏任务,按照执行顺序,也是要排队的。

    再看一个例子:

    console.log(1);
    setTimeout(() => {
      console.log("setTimeout");
    }, 10);
    console.log(2);
    for (let index = 0; index < 10000; index++) {
      console.log(10000);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    定时器设置10毫秒,下面循环10000次,肯定会超过10毫秒了,应该会先输出setTimeout了吧,实时并不是这样,因为for是同步的,但是JavaScript引擎一直在忙没空去搭理它。

    image.png

    总结

    • JavaScript中的任务分为同步任务和异步任务,异步任务又有宏任务和微任务;
    • JavaScript先查找同步任务,然后再去任务队列中查找微任务,最后才去任务队列中查找宏任务;
    • 执行顺序:同步任务 》微任务 》宏任务。
  • 相关阅读:
    【计算机网络】计算机网络中的一些基本概念
    Flyme预计明年上车!星纪时代携手魅族,推动智行生态完美融合
    基于Android+JavaWeb的医疗信息(电子病历)检索管理系统
    【UNI】对接蓝牙智能笔遇到的问题
    「实用场景教程」如何用日程控件DHTMLX Scheduler制作酒店预订日历?(一)
    linux性能分析(三)查看系统的性能指标
    【Vue3】自定义指令
    计算机组成原理-总线详细讲解(持续更新中)
    什么是协程?
    今天不写代码,聊聊热门的知识图谱
  • 原文地址:https://blog.csdn.net/qq_27829333/article/details/134281950