js~eventLoop 事件循环

事件循环的概念:

因为js是单线程的。所以js是从上至下按顺序运行下去的,顺序执行代码,那么,如果js代码中间向后台发送一个ajax请求,就要等到请求等到结果后才会继续向下执行。如果请求耗时过长,或者请求报错,会导致用户体验不好。因此,就有了同步任务、异步任务的区别。

同步任务和异步任务在js中是如何执行的呢?js的代码运行会形成一个主线程和一个任务队列。主线程会从上到下一步步执行我们的js代码,形成一个执行栈。同步任务就会被放到这个执行栈中依次执行。而异步任务被放入到任务队列中执行,执行完就会在任务队列中打一个标记,形成一个对应的事件。当执行栈中的任务全部运行完毕,js会去提取并执行任务队列中的事件。这个过程是循环进行的,这就是我们今天想要了解的event loop

因为js的event loop机制,所以大家不要认为setTimeOut设置的事件到了延迟时间就是被执行。如果你的执行栈任务没有被全部执行完,清空。setTimeOut事件执行的时间很有可能是要大于你设置的延时参数。

宏任务微任务:

 

异步任务之间是有执行优先级的区别的。不同的异步任务会被分为两类,微任务和宏任务

 

宏任务: 需要多次事件循环才能执行完,事件队列中的每一个事件都是一个宏任务。

 

常见的宏任务:定时器,延时器,ajax, 交互事件

 

微任务: 微任务是一次性执行完的。微任务通常来说是需要在当前task执行结束后立即执行的任务,例如对一些动作做出反馈或者异步执行任务又不需要分配一个新的task,这样便可以提高一些性能。

 

常见的微任务:promise.then(),  process.nextTick , MutationObserver

    

宏任务中包含微任务时,按照顺序循环执行   

new Promise((reslove,reject)=>{
            console.log("romise start")
            reslove("data")
        }).then((res)=>{ console.log(res) })

        setTimeout(()=>{
            console.log("settimeout start")
            new Promise((reslove,reject)=>{
                console.log("romise1111 start")
                reslove("data romise11")
            }).then((res)=>{console.log(res)})
            console.log("settimeout end")
        },0)

        setTimeout(()=>{
            console.log("settimeout222 start")
            new Promise((reslove,reject)=>{
                console.log("romise2222 start")
                reslove("data romise2222")
            }).then((res)=>{console.log(res)})
            console.log("settimeout222 end")
        },0)
console.log(10000)

以上代码执行效果如下:

romise start
10000
data

首先程序进入到代码块执行scrit主线程任务 romise start  , 10000,然后执行了Promise.then()  // data


settimeout start
romise1111 start
settimeout end
data romise11

延时器属于宏任务,但是延时器里面还有同步任务和微任务,首先执行完了同步任务 settimeout start , romise1111 start , settimeout end,然后执行微任务。

第一个宏任务执行完毕了,接着开始执行第二个宏任务。

settimeout222 start
romise2222 start
settimeout222 end
data romise2222

 

微任务中混合宏任务 相互混合

{
            console.log(1);

            setTimeout(() => {
                console.log(2);
            })

            new Promise((resolve) => {
                console.log(3)
                resolve()
            }).then(() => {
                setTimeout(() => {
                    console.log(4);
                })
            }).then(() => {
                console.log(5)
            })

            console.log(6)

            setTimeout(() => {
                console.log(7)
                new Promise(resolve => {
                    console.log(8)
                    setTimeout(() => {
                        console.log(9)
                    })
                    resolve()
                }).then(() => {
                    console.log(10)
                })
            }, 500)

            new Promise(resolve => {
                console.log(11)
                resolve()
            }).then(() => {
                console.log(12)
                setTimeout(() => {
                    console.log(13)
                }, 0)
            })
            
            console.log(14)
            // 1 3 6 11 14 主线程
            // 12 5
            // 宏任务 2 4 13 7 8 10 9
        } 

 

原文地址:https://www.cnblogs.com/rose-sharon/p/12427214.html