手记

【备战春招】第4天 破解JavaScript高级玩法 第十一讲

课程章节: “永动机”- 事件循环

主讲老师: Cloud

课程内容:

今天学习的内容包括:

宏任务,微任务和事件循环

课程收获:

11.1 心得:

async+await

async function async1() {
    console.log("async1 start");
    await async2();
    // .then()
    console.log("async1 end");
}
async function async2() {
    console.log("async2");
}
// new Promise(function(resolve, reject) {
//     resolve(undefined);
// })

console.log("main start");

setTimeout(function () {
    console.log("setTimeout");
});
async1();
new Promise(function (resolve) {
    console.log("promise 构造");
    resolve();
}).then(function () {
    console.log("promise then");
});

console.log("main end");


// 宏任务:
// 微任务:


/* 输出 */
// main start
// async1 start
// async2
// promise 构造
// main end
// async1 end
// promise then
// setTimeout


Promise

//第一个promise
Promise.resolve()
    .then(() => {
        console.log(1);
    })
    .then(() => {
        console.log(3);
        return Promise.resolve(7);
    })
    .then((res) => {
        console.log(res);
    });

//第二个promise
Promise.resolve()
    .then(() => {
        console.log(2);
    })
    .then(() => {
        console.log(4);
    })
    .then(() => {
        console.log(5);
    })
    .then(() => {
        console.log(6);
    })
    .then(() => {
        console.log(8);
    });
<!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>
        <style>
            .outer-btn{
                position: relative;
                width: 300px;
                height: 100px;
                background: red;
            }

            .inner-btn{
                position: relative;
                width: 200px;
                height: 80px;
                background: yellow;
            }
        </style>
    </head>

    

    <body>
        <div class="outer-btn">
            外部按钮
            <div class="inner-btn">内部按钮</div>
        </div>
        <script>
            var outerBtn = document.querySelector(".outer-btn");
            var innerBtn = document.querySelector(".inner-btn");

            new MutationObserver(function () {
                console.log("mutate 微任务");
            }).observe(outerBtn, {
                //观察属性变化
                attributes: true,
            });

            //点击方法
            function onClick() {
                console.log("click");
                setTimeout(function () {
                    console.log("timeout 宏任务");
                });
                Promise.resolve().then(function () {
                    console.log("promise 微任务");
                });

                outerBtn.setAttribute("data-number", Math.random());
            }

            outerBtn.addEventListener("click", onClick);
            innerBtn.addEventListener("click", onClick);


            // click时:
            // 宏任务队列:onClick(inner), onClick(outer)



            // 事件循环: 执行第一个onClick(inner)
            // 执行前:
            // 宏任务队列:onClick(inner), onClick(outer)
            // 微任务任务队列:

            //// console.log("click");

            // 执行后:
            // 宏任务队列: onClick(outer), setTimeout
            // 微任务任务队列:promise, mutate

            //// 执行微任务输出: promise 微任务, mutate 微任务




            //事件循环: 执行第二个onClick(outer)
            // 执行前:
            // 宏任务队列:onClick(outer), setTimeout
            // 微任务任务队列:

            //// console.log("click");

            // 执行后:
            // 宏任务队列: setTimeout, setTimeout
            // 微任务任务队列:promise, mutate

            ///// 执行微任务输出: promise 微任务, mutate 微任务




            // 下一个事件循环
            // 执行前 宏任务队列: setTimeout, setTimeout
            //// 输出 timeout 宏任务
            // 执行后 宏任务队列: setTimeout




            // 再下一个事件循环
            // 执行前 宏任务队列: setTimeout
            //// 输出 timeout 宏任务
            // 执行后 宏任务队列:




        </script>
    </body>
</html>
<!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>
        <style>
            .outer-btn{
                position: relative;
                width: 300px;
                height: 100px;
                background: red;
            }

            .inner-btn{
                position: relative;
                width: 200px;
                height: 80px;
                background: yellow;
            }
        </style>
    </head>

    

    <body>
        <div class="outer-btn">
            外部按钮
            <div class="inner-btn">内部按钮</div>
        </div>
        <script>
            var outerBtn = document.querySelector(".outer-btn");
            var innerBtn = document.querySelector(".inner-btn");

            new MutationObserver(function () {
                console.log("mutate 微任务");
            }).observe(outerBtn, {
                //观察属性变化
                attributes: true,
            });

            //点击方法
            function onClick(ev) {
                console.log("click", ev.currentTarget.className);

                setTimeout(function () {
                    console.log("timeout 宏任务");
                });

                Promise.resolve().then(function () {
                    console.log("promise 微任务");
                });

                outerBtn.setAttribute("data-number", Math.random());
            }

            outerBtn.addEventListener("click", onClick);
            innerBtn.addEventListener("click", onClick);

            // 
            innerBtn.click();

            // 执行第一个onClick(inner)
            // 执行前:
            // 宏任务队列:
            // 微任务任务队列:

            //// console.log("click");

            // 执行后:
            // 宏任务队列: setTimeout
            // 微任务任务队列:promise, mutate



            // 执行第二个onClick(outer)
            // 执行前:
            // 宏任务队列:setTimeout
            // 微任务任务队列:promise, mutate

            //// console.log("click");

            // 执行后:!!!! MutationObserver 不会再添加
            // 宏任务队列: setTimeout, setTimeout
            // 微任务任务队列:promise, mutate, promise,

            ///// 执行微任务输出: promise 微任务, mutate 微任务,promise 微任务,


            // 下一个事件循环
            // 执行前 宏任务队列: setTimeout, setTimeout
            //// 输出 timeout 宏任务
            // 执行后 宏任务队列: setTimeout



            // 再下一个事件循环
            // 执行前 宏任务队列: setTimeout
            //// 输出 timeout 宏任务
            // 执行后 宏任务队列:




        </script>
    </body>
</html>
<!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>
        <style>
            .outer-btn{
                position: relative;
                width: 300px;
                height: 100px;
                background: red;
            }

            .inner-btn{
                position: relative;
                width: 200px;
                height: 80px;
                background: yellow;
            }
        </style>
    </head>

    

    <body>
        <div class="outer-btn">
            外部按钮
            <div class="inner-btn">内部按钮</div>
        </div>
        <script>
            var outerBtn = document.querySelector(".outer-btn");
            var innerBtn = document.querySelector(".inner-btn");

            new MutationObserver(function () {
                console.log("mutate 微任务");
            }).observe(outerBtn, {
                //观察属性变化
                attributes: true,
            });

            //点击方法
            function onClick() {
                console.log("click");

                setTimeout(function () {
                    console.log("timeout 宏任务");
                });

                
                Promise.resolve().then(function () {
                    console.log("promise 微任务");
                });

                outerBtn.setAttribute("data-number", Math.random());
            }

            outerBtn.addEventListener("click", onClick);
            innerBtn.addEventListener("click", onClick);


            
            //点击
            const evObj=  document.createEvent("MouseEvents");
            evObj.initEvent("click", true, true);
            evObj.eventType = 'message';
            innerBtn.dispatchEvent(evObj);

        </script>
    </body>
</html>
<!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>
        <style>
            .outer-btn{
                position: relative;
                width: 300px;
                height: 100px;
                background: red;
            }

            .inner-btn{
                position: relative;
                width: 200px;
                height: 80px;
                background: yellow;
            }
        </style>
    </head>

    

    <body>
        <div class="outer-btn">
            外部按钮
        </div>
        <script>
            var outerBtn = document.querySelector(".outer-btn");

            new MutationObserver(function () {
                console.log("mutate 微任务");
            }).observe(outerBtn, {
                //观察属性变化
                attributes: true,
            });

            //点击方法
            function onClick() {
                console.log("click");

                outerBtn.setAttribute("data-number", Math.random());
                outerBtn.setAttribute("data-number", Math.random());
                outerBtn.setAttribute("data-number", Math.random());
            }

            outerBtn.addEventListener("click", onClick);

        </script>
    </body>
</html>

<!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>
    <style>
        .option-btn {
            position: relative;
            width: 200px;
            height: 200px;
            font-size: 20px;
            color: #fff;
            background: red;
        }
    </style>
</head>

<body>

    <div>
        <button id="btnStart">触发按钮</button>
    </div>

    <button class="first-btn">首次点击</button>
    <button class="second-btn"> 二次点击</button>
    <script>

        var firstBtn = document.querySelector(".first-btn");
        var secondBtn = document.querySelector(".second-btn");
        //同步耗时操作
        function asyncSleep(duration) {
            const now = Date.now();
            while (now + duration > Date.now()) {

            }
        }

        firstBtn.onclick = function () {
            console.log("firstBtn onClick", new Date().toLocaleTimeString())
            //2. 假设需要执行3s
            console.time("firstBtn:cost")
            asyncSleep(3000);
            Promise.resolve().then(() => {
                console.log("执行 微任务 promise", new Date().toLocaleTimeString());
                //3. 假设需要执行2s
                console.time("promise:cost");
                asyncSleep(2000);
                console.timeEnd("promise:cost");
            })
            console.timeEnd("firstBtn:cost")
        }

        secondBtn.onclick = function () {
            console.log("secondBtn onClick", new Date().toLocaleTimeString())
            //4. 假设需要执行1s
            console.time("secondBtn:cost")
            asyncSleep(1000);
            console.timeEnd("secondBtn:cost")
        }

        btnStart.onclick = function () {
            //1. 假设需要执行5s
            console.log("main:", new Date().toLocaleTimeString())
            console.time("main:cost")
            asyncSleep(5000);
            console.timeEnd("main:cost")
        }

    </script>
</body>

</html>
<!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>
    <style>
    </style>
</head>

<body>
    <button id="btnLog" class="btnLog">操作点击事件</button>
    <button class="start">开始添加dom</button>
    <script>

        var startBtn = document.querySelector(".start");
        var array = [];
        for (var i = 1; i <= 300000; i++) {
            array.push(i);   //制造300000条数据
        };
        console.log("数据制造完成");
        //渲染数据
        var renderDomList = function (data) {
            for (var i = 0, l = data.length; i < l; i++) {
                var div = document.createElement('div');
                div.innerHTML = `列表${i}`;
                document.body.appendChild(div);
            }
        };

        startBtn.onclick = function () {
            console.log("startBtn clicked:", new Date().toLocaleTimeString());
            renderDomList(array);
        }

        btnLog.onclick = function () {
            console.log("btnLog clicked:", new Date().toLocaleTimeString());
        }
    </script>
</body>

</html>
<!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>
    <style>
    </style>
</head>

<body>
    <button id="btnLog" class="option-btn">操作点击事件</button>
    <button class="start">开始添加dom</button>
    <script>

        var startBtn = document.querySelector(".start");

        const step = 200;

        var array = [];
        for (var i = 1; i <= 300000; i++) {
            array.push(i);   //制造300000条数据
        };
        console.log("数据制造完成");

        //渲染数据
        var renderDomList = function (data, startIndex, endIndex) {
            if (startIndex < endIndex && endIndex <= data.length) {
                setTimeout(() => {
                    for (let i = startIndex; i < endIndex; i++) {
                        var div = document.createElement('div');
                        div.innerHTML = `列表${i}`;
                        document.body.appendChild(div);
                    }
                    let nextIndex = endIndex + step > data.length ? data.length : endIndex + step;
                    let nextStartIndex = endIndex > data.length ? data.length : endIndex;
                    renderDomList(data, nextStartIndex, nextIndex);
                }, 0)
            }
        };

        startBtn.onclick = function () {
            console.log("startBtn clicked:", new Date().toLocaleTimeString());
            renderDomList(array, 0, 0 + step);
        }

        btnLog.onclick = function () {
            console.log("btnLog clicked:", new Date().toLocaleTimeString());
        }
    </script>
</body>

</html>

0人推荐
随时随地看视频
慕课网APP