js 事件循环机制、宏任务微任务

news/2024/7/19 14:47:37 标签: js, javascript, 事件循环, 宏任务, Promise

宏任务和微任务

  • 定义
    • 宏任务: 常用的包括setTimeout,setInterval
    • 微任务: 常用的包括Promise. then finally catch, process.nextTick
  • 执行顺序为:微任务先于宏任务执行
javascript">        setTimeout(function () {
            console.log('setTiemout宏任务')
        }, 0)

        new Promise(resolve => {
            resolve()
            console.log('Promise内部的普通语句,也是同步任务')
        })
            .then(() => {
                console.log('then,这里就是微任务')
            })

        console.log('Promise外部的同步任务')

        /*输出结果为
         *Promise内部的普通语句,也是同步任务
         *Promise外部的同步任务
         *then,这里就是微任务
         *setTiemout宏任务
         */

透彻浏览器事件循环机制

在这里插入图片描述

  • 也就是说,浏览器执行js,先执行主线程的同步任务,在途中如果遇到宏任务,会使其进入宏任务队列;微任务也是同理。
  • 主线程同步任务都执行完毕后,会执行此时可以执行的所有微任务;微任务执行完毕后,会执行宏任务队列的第一个任务;执行完毕后,然后就去查看微任务队列是否有可执行的微任务,如果有,全部执行;没有的话,再去执行宏任务队列的第一个任务。
  • 执行一次宏任务后,再执行此时全部可执行的微任务,再到执行宏任务,称为一次事件循环
  • 浏览器事件循环机制和Node事件循环机制有所区别,这里只讨论前者。
  • 栗子:
javascript">    //1. 主线程直接执行1
    console.log('1');

    //进入宏任务队列1
    setTimeout(function() {
        //5. 直接执行
        console.log('2');

        //进入微任务队列3
        process.nextTick(function() {
            //6. 微任务执行3
            console.log('3');
        })

        new Promise(function(resolve) {
            //7. 直接执行
            console.log('4');
            resolve();
        })
        //进入微任务队列4
        .then(function() {
            //8. 微任务执行4
            console.log('5')
        })
    })

    //进入微任务队列1
    process.nextTick(function() {
        //3. 微任务执行1
        console.log('6');
    })

    new Promise(function(resolve) {
        //2. 主线程直接执行2
        console.log('7');

        resolve();
    })
    //进入微任务队列2
    .then(function() {
        //4. 微任务执行2
        console.log('8')
    })
    
    //进入宏任务队列2
    setTimeout(function() {
        //9. 直接执行
        console.log('9');

        //进入微任务队列5
        process.nextTick(function() {
            //11. 微任务执行5
            console.log('10');
        })

        new Promise(function(resolve) {
            //10. 直接执行
            console.log('11');
            resolve();
        })
        //进入微任务队列6
        .then(function() {
            //12. 微任务执行6
            console.log('12')
        })
    })

    //输出结果为:1,7,6,8,2,4,3,5,9,11,10,12
  • 上面的代码中,有三次事件循环
    • 第一次循环:主线程直接输出1,7,然后执行全部的微任务,输出6,8。
    • 第二次循环:第一个setTimeout宏任务进入主线程,直接输出2,4,然后执行全部的微任务,输出3,5。
    • 第三次循环:第二个setTimeout宏任务进入主线程,直接输出9,11,然后执行全部的微任务,输出10,12。
    • PS: 在宏任务中的微任务,一定会执行完毕后才继续执行其他的宏任务,就像上面代码中,先输出的是第一个setTimeout的同步代码,然后是微任务代码,而不是第二个setTimeout的同步代码。

结语

如果对你有帮助的话,请点一个赞吧


http://www.niftyadmin.cn/n/1257958.html

相关文章

easyUI自带的时间插件日期选择、月份选择、时间选择的使用

参考文件&#xff1a;点击下载 1.日期选择 只要将class设置成easyui-datebox就可以了&#xff0c;当然前提是已经应用了easyui的js <input type"text" class"easyui-datebox" id"datetime"> 2.时间选择 默认的时间选择是精确到年月日时分…

node gbk转utf8

最近在做node爬虫的时候&#xff0c;发现利用axios返回的网页源码有中文乱码&#xff0c;一看网页的编码方式得知是gbk编码。研究了一下&#xff0c;问题解决&#xff0c;分享出来防止以防大家踩坑。 安装 iconv-lite node默认不支持gbk编码方式 $ npm i iconv-lite这个模块…

支付宝接入

支付宝开发中return_url和notify_url的区别分析 关于支付宝即时到帐异步通知&#xff08;notify_url&#xff09;一点总结 支付宝接口使用文档说明 支付宝异步通知(notify_url)与return_url. 转载于:https://www.cnblogs.com/jingzhishen/p/6753860.html

油猴脚本之弹幕屏蔽

前言 笔者是平常比较喜欢看虎牙直播&#xff0c;但是网页版虎牙并没有弹幕屏蔽功能&#xff0c;在油猴上也没有找到相关的脚本&#xff0c;自己就做了一个。 说明 笔者的设计初衷是在弹幕还没有进入DOM渲染流之前&#xff0c;也就是在刚请求完弹幕之后&#xff0c;对弹幕的内…

详谈js for循环和数组遍历方法

前言 早就想写一篇博客来谈谈js中的循环和一些循环的方法&#xff0c;这次有时间来说说。 正文 一. for类循环 1. for — 传统的方式 for (let index 0; index < arr.length; index) {console.log(arr[index])}范围&#xff1a; 可遍历数组&#xff0c;不可遍历对象 迭…

Vue 中使用 Sass 踩的坑

这两天在vue脚手架中使用Sass&#xff0c;踩了几个坑&#xff0c;分享出来。 在 Vue cli3 中安装 $ npm i sass sass-loader -D首先&#xff0c;要安装的是两个&#xff0c;sass sass-loader其次&#xff0c;一定要安装在开发依赖中&#xff0c;因为它是CSS的预处理器。-D即为…

Sass学习

前言 这两天刚好学到sass&#xff0c;分享一下自己在学习过程中总结的点 正文 基本用法 sass中导入另一个sass import "路径" 注释 单行注释 //&#xff0c;编译后省略&#xff0c;只会保留在sass源文件中多行注释 /* */ &#xff0c;会保留在编译后的css文件中重…

vue 中编写404页面

前言 今日给自己项目添加404页面时&#xff0c;踩了一点坑&#xff0c;分享给大家。 正文 <div class"_404"><h2 class"m-0">抱歉&#xff0c;页面未找到&#xff0c;<span>{{countDown}}</span>s后自动跳转到<a href"j…