• 微任务、宏任务与Event-Loop


    参考1:https://www.cnblogs.com/lucy-xyy/p/11652286.html

    参考2:https://www.cnblogs.com/yugege/p/9598265.html

    事件循环机制

    JavaScript 语言的一大特点就是单线程,也就是说,同一个时间只能做一件事,但是一个任务耗时太长,那么后面的任务就需要等待,为了解决这种情况,将任务分为了同步任务和异步任务,而异步任务又可以分为微任务和宏任务。

    同步和异步任务分别进入不同的执行环境,同步的进入主线程,即主执行栈,异步的进入 Event Queue (任务队列)。主线程内的任务执行完毕为空,会去 Event Queue 读取对应的任务,推入主线程执行。 上述过程的不断重复就是我们说的 Event Loop (事件循环)。 

    所以异步操作都是放到事件循环队列里面,等待主执行栈来执行的,也并没有专门的异步执行线程。

    宏任务和微任务

    task分为两大类, 分别是 Macro Task (宏任务)和 Micro Task(微任务), 并且每个宏任务结束后, 都要清空所有的微任务。

    macro task宏任务主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)

    micro task微任务主要包含:Promise函数的 .then 语句、 .catch 语句、 .finally 语句,async函数await表达式后面的语句、MutaionObserver、process.nextTick(Node.js 环境)

    补充:在 node 环境下,process.nextTick 的优先级高于 Promise函数中的then语句

    从图中可以看到,宏任务执行顺序优先于微任务,所以JS执行顺序为:script>清空微任务>宏任务>清空微任务>宏任务>清空微任务……直至清空任务队列

    举个栗子

    async function async1() {
        console.log(2); // 顺序4.同步代码最先执行,输出2
        await fn(); // 顺序5:await会阻塞await后面代码的执行(将await后面的代码,也就是这里的console.log(7)变成微任务,放进任务队列等待执行),但不阻塞await表达式,同时await会跳出async函数
        console.log(7); // 顺序10:await执行完毕,执行await后的微任务,输出7,然后执行后续的同步代码及await时生成的微任务
    }
    function fn() { 
        // 顺序6:执行fn,输出3,await跳出async函数让出线程,执行async后面的代码
        console.log(3); 
    }
    console.log(1);     // 顺序1.由上而下,同步代码最先执行,输出1
    setTimeout(function () {    // 顺序2.setTimeout为宏任务,进入任务队列进行等待执行
        console.log(10);    // 顺序13.无同步代码、无微任务,开始执行下一个宏任务,输出10
    }, 0)
    async1();   // 顺序3.同步代码,执行方法async1
    new Promise(function (resolve) {
        console.log(4); // 顺序7:执行Promise同步代码,输出4,记录.then为微任务1,进入队列等待执行
        resolve();
    }).then(function () {
        console.log(8); // 顺序11.无同步代码,依次执行剩余微任务,输出8
    });
    new Promise(function (resolve) {
        console.log(5); // 顺序8:执行Promise同步代码,输出5,记录.then为微任务2,进入队列等待执行
        resolve();
    }).then(function () {
        console.log(9); // 顺序12.无同步代码,执行剩余微任务2,输出9
    });
    console.log(6); // 顺序9:执行同步代码,输出6
  • 相关阅读:
    CentOS搭建LAMP环境
    CentOS下为Apache部署Symantec SSL证书并实现强制https访问
    [Raspi]树莓派4B装机使用上手指南
    [FPGA]Verilog利用PWM调制完成RGB三色彩虹呼吸灯
    [FPGA]浅谈LCD1602字符型液晶显示器(Verilog)
    [FPGA]Verilog实现JK触发器组成的8421BCD码十进制计数器
    [FPGA]Verilog实现可自定义的倒计时器(24秒为例)
    [FPGA]Verilog实现8位串并转换器HC595
    [FPGA]Verilog实现寄存器LS374
    STM32F407之USART
  • 原文地址:https://www.cnblogs.com/jing-zhe/p/13791711.html
Copyright © 2020-2023  润新知