浏览器事件循环

事件循环(也叫EventLoop)

js执行是单线程执行代码,如果没有事件队列,js执行代码会被堵塞,所以需要事件队列,当js执行代码时遇到script、setTimeout、 promise、 渲染器、 用户交互事件、或引入外部链接link等微任务和宏任务时(也就是异步代码),需要将这些微任务和宏任务按照顺序放到微/宏任务队列中,当js代码从上到下全部执行完毕后,查看事件队列(eventLoop)中有没有微/宏任务,如果有,先执行微任务,清空微任务队列中的所有微任务,当清空完所有的微任务后,在执行宏任务,一个一个执行,直到所有的宏任务执行完毕。
在这里插入图片描述
上图执行顺序简易图:
在这里插入图片描述

根据下面的代码小结如下:
  • 宏任务中包含微任务的情况

如果是宏任务的话 会将所有的宏任务放到队列中,一个一个宏任务执行,当执行第一个宏任务,如果宏任务里面有微任务,将宏任务里面所有的微任务清除干净,然后再会执行第二个宏任务

  • 如果宏任务里面包含宏任务的情况

将所有执行栈的宏任务一次放到队列中,然后执行第一个宏任务,当执行第一个宏任务时,发现宏任务里面还有宏任务,则将里面的宏任务取出,放到队列任务中进行排队,当所有第一层的宏任务执行完毕后,则按照顺序执行第二层排好队的宏任务

  • 微任务中包含微任务

将所有执行栈的微任务放到队列中,等待执行,当执行第一个微任务的时候,发现微任务里面还有微任务,则将里面的微任务取出
放到微任务队列后面排队 当所有的第一层微任务执行完成,按照排队执行里面的微任务

	<button id="button"></button>
    <script>
        let button = document.querySelector('#button')
        button.addEventListener('click', () => {
    
    
            console.log('listener1');
            Promise.resolve().then(() => console.log('micro task1'))
        })
        button.addEventListener('click', () => {
    
    
            console.log('listener2');
            Promise.resolve().then(() => console.log('micro task2'))
        })
        // button.click(); // click1() click2()
        // listener1  micro task1 listener2 micro task2
        Promise.resolve().then(() => {
    
    
            fn()
            fn2()
        })
        function fn() {
    
    
            Promise.resolve().then(() => {
    
    
                console.log('promise1')
                // return Promise.resolve()
                Promise.resolve().then(() => {
    
    
                    console.log("promise2")
                })
            })
        }
        function fn2() {
    
    
            Promise.resolve().then(() => {
    
    
                console.log("promise 3")
                // return Promise.resolve()
                Promise.resolve().then(() => {
    
    
                    console.log('promise4')
                })
            })
        }

        setTimeout(() => {
    
    
            console.log(1)
            setTimeout(() => {
    
    
                console.log(2)
            })
        })
        setTimeout(() => {
    
    
            console.log(3)
            setTimeout(() => {
    
    
                console.log(4)
            })
        })
    </script>
经典练习题巩固微/宏任务(想知道答案,动手敲一敲,有你意想不到的收获)
 		Promise.resolve().then(() => {
    
    
            console.log('Promise1')
            setTimeout(() => {
    
    
                console.log('setTimeout2')
            }, 0);
        })
        setTimeout(() => {
    
    
            console.log('setTimeout1');
            Promise.resolve().then(() => {
    
    
                console.log('Promise2')
            })
        }, 0);
  		console.log(1);
        async function async() {
    
    
            console.log(2);
             await console.log(3);//提点一下:这里的写法相当于 yield console.log(3) 
            // Promise.resolve(console.log(3)).then(()=>console.log(4))
             console.log(4)
        }
        setTimeout(() => {
    
    
            console.log(5);
        }, 0);
        const promise = new Promise((resolve, reject) => {
    
    
            console.log(6);
            resolve(7)
        })
        promise.then(res => {
    
    
            console.log(res)
        })
        async();
        console.log(8);

猜你喜欢

转载自blog.csdn.net/weixin_47818125/article/details/129845788
今日推荐