JS事件循环,宏任内务,微任务,当前执行队列。

 

//同步任务1
        function click1() {
            //微任务
            new Promise((resolve, reject) => {
                resolve("click1引发的微任务");
            }).then((val) => {
                console.log(val);
            });

            //宏任务
            setTimeout(() => {
                console.log("click1引发的宏任务");
            }, 0);

            console.log("click1");
            sleep(2000);
        }
        //同步任务2
        function click2() {
            console.log("click2");
            //微任务
            new Promise((resolve, reject) => {
                resolve("click2引发的微任务");
            }).then((val) => {
                console.log(val);
            });

            //宏任务
            setTimeout(() => {
                console.log("click2引发的宏任务");
            }, 0);
        }

        //参数n为休眠时间,单位为毫秒:
        function sleep(n) {
            var start = new Date().getTime();
            //  console.log('休眠前:' + start);
            while (true) {
                if (new Date().getTime() - start > n) {
                    break;
                }
            }
            // console.log('休眠后:' + new Date().getTime());
        }


//输出顺序
click1
click1引发的微任务
click2
click2引发的微任务
click1引发的宏任务
click2引发的宏任务

百度查询了js事件循环和异步队列的相关资料,以上代码用于测试验证。

1.事件任务

2.宏任务(setTimeout/setInterva等)

3.微任务(Promise)

 

测试浏览器:Chrome、Edge。

总结:

我将其分为:当前执行队列、宏任务队列、微任务队列。

1.事件触发时将事件任务加入当前执行队列开始执行,每完成一个任务后将执行微任务队列中所有任务。当前执行队列完成后更新UI。(测试发现DOM的操作在每个任务(方法/函数)结束后更新,但是UI只会在当前执行队列完成后才会更新)UI更新后本轮事件循环结束。

2.下轮事件循环,从宏任务队列中取出一个任务加入当前执行队列开始执行(如果有)。在执行过程中如果触发事件即加入当前执行队列,宏任务执行完毕后执行微任务队列,然后再开始执行事件任务。当前执行队列完成后更新UI结束本轮事件循环。

3.宏任务队列中,每轮事件循环仅取出一个宏任务执行。加入当前执行队列后和事件任务无异。当前执行队列每完成一个任务,就需要清理所有微任务。

 

 

随笔移植,原文地址:https://zhuanlan.zhihu.com/p/367363272

posted @ 2022-05-24 19:31  状态的状  阅读(28)  评论(0编辑  收藏  举报