宏任务与微任务(事件循环)


1. 概念:

事件循环指的就是浏览器执行js的一个机制,其机制就是js引擎在不停的询问事件队列是否有可执行的任务(事件),将任务放到执行栈的机制

过程如下:

script宏任务=》同步代码=》微任务》=》渲染=》宏任务

2. 宏微任务

异步任务被拆分成宏微任务

2.1 宏任务

常见的宏任务有:

(1)定时器setTimeout和setInterval

(2)IO输入输出 网络请求

(3)注册的事件回调,比如click事件的回调

(4)整个script标签中的代码,也就是全局的代码,算一个宏任务

2.2 微任务

常见的微任务有:

(1)promise.then

(2)promise.cathch

(3)promise.finally

(4)queuemicrotask

(5)MutationObsever

3. 示例

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <!-- 阻塞 -->
    <!-- <script>
        startTime = new Date().getTime()
        do {
            endTime = new Date().getTime()
            console.log(endTime - startTime);
        } while (endTime - startTime <= 2000)

    </script> -->
</head>

<body>

    <a href="https://zhuanlan.zhihu.com/p/78113300">查看</a>



</body>
<script src="./js/jquery-1.10.2.js"></script>
<script src="./assets/js/axios/axios-0.21.1.js"></script>
<script src="./js/layer/layer.js"></script>
<script>

    // 尽量不要讨论渲染,渲染这个步骤不一定 可能和运行环境有关 window谷歌浏览器有时会宏任务alert阻塞
    
    // js操作dom的渲染,有时候又不阻塞,甚至不加window.onload,初始的渲染都会阻塞
    
    // 而火狐不管你alert用在哪里都不阻塞 只要不是同步代码的alert都不回阻塞

    // import App from './common.js';

    //这里如果不加window.onload html渲染会暂停(alert导致页面元素丢失并不是阻塞的问题),等待js执行结束 https://www.cnblogs.com/songyao666/p/16112629.html

    let data = { "User": { "user_name": "admin", "password": "yoshop" } };
    axios({
        method: 'post',
        url: 'https://yoshop.guet.link/index.php?s=/store/passport/login',
        headers: {
            // 'Content-Type': 'application/x-www-form-urlencoded',
            "X-Requested-With": "xmlhttprequest"
        },
        data: data,
    }).then((res) => {
        console.log('请求成功');
    })



    var body = $('body');
    body.append(`<button type='submit'>按我看看</button>`);


    setTimeout(() => {
        console.log('宏任务执行1');
    }, 0)

    //自己封装的axios请求方法 axios这里是异步then微任务 
    // App._post_form('adminUser/login', {}, (res) => {
    // }, (res) => {
    //     console.log('IO结束then微任务执行2');
    // }) 

    Promise.resolve().then(() => {
        console.log('微任务执行1');

        let startTime = new Date().getTime()
        let endTime = new Date().getTime()
        do {
            endTime = new Date().getTime()
        } while (endTime - startTime <= 5000)


        setTimeout(() => {
            console.log('宏任务执行4');
        }, 5000)
    });

    console.log('同步代码1');

    Promise.resolve().then(() => {
        console.log('微任务执行2');
        setTimeout(() => {
            console.log('宏任务执行3');

        }, 1000)
    });


</script>

</html>

文章作者: iamfugui
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 iamfugui !
评论
  目录