阅读 434

一次性彻底了解js event loop 事件循环

js事件大致可以分为微任务,宏任务,同步任务,异步任务

1,微任务 Promise.then()  [非promise]   ,  process.nextTrick()    [node中]  等等...

2,宏任务  setTimeout()  html整体代码 setInterval()  等等...

3,异步任务  setTimeout()  setInterval() ajax请求  等等...

4,同步任务  [这个不知道怎么举例...]  

eg:
    //微任务 - 同步任务
    new Promise((resolve,reject)=>{   //tip:promise是同步任务
        console.log(1);               
        resolve();
    })
    .then(()=>{                        // promise.then()是微任务
        console.log(2)
    })

    //打印结果
    1;
    2;
    

    /*
        首先我们先了解js执行机制,由于js是单线程任务,会有一个event loop循环机制,
        所以会一步一步执行,
        也就是队列,而执行时先执行宏任务,等到宏任务执行完执行在执行微任务,
        例如上面的例子:
        先将同步任务pormise放入队列执行[输出1] => 发现resolve(.then说你执行完了,该我了) 
                                                同步任务执行完毕
                                             => 执行微任务[输出2]
    */复制代码

eg:
    //异步任务 - 宏任务
    console.log(1);        //同步任务
    setTimeout(()=>{       // 宏任务-异步任务
        console.log(2)
    })
    console.log(3)

    /*
        首先将console.log(1)放入event loop循环机制里 打印1
         =>         发现宏任务,且宏任务是异步的,将setTimeout放入event loop循环中

          =>
        
         发现同步任务console.log(3),将console.log(3)放入event loop执行,
    
          并将同步任务放在异步任务之前执行  打印3

        =>
    
        同步任务执行完,异步任务,你们都完事了,该我了吧. 打印3
        
    */
复制代码

来看一道有趣的面试题

console.log(1);

setTimeout(function(){
    console.log(2)
})

new Promise(function((resolve,reject)=>{
    console.log(3);
})
.then(()=>{
    console.log(4)
});




/*
       首先我们来分析下这道题,
        
       发现事件,开启event loop循环机制

        =>

       先将console.log(1)放入event loop 循环机制中
    
        =>
        
        发现宏任务,将setTimeout放入event loop循环机制中,
        
        发现宏任务setTimeout 是异步任务, 给他单独开条路,让他执行

        =>
    
        发现同步任务promise, 将同步任务放入event loop 循环机制中

         打印结果依次为[1 => 3 => 2 ]

        这里解释一下为什么微任务promise().then()没有执行

        [在执行同步任务promise时,没有发现resolve()函数,因此无法继续向下执行,

         promise()一直处于pedding状态,如果在同步任务promise()中加了resolve()函数

         那么微任务promise().then()会执行,打印结果依次为[1 => 3 => 4 => 2]
         
          这样很多人会说,setTimeout不是宏任务吗? 不是宏任务先执行吗? 

            解释一下,setTimeout是宏任务但是他是异步任务,异步任务会等到线程上的任务都结束

            之后才会输出.
         ]

        
*/

复制代码

eg:
    //下面看下这道题的进阶版本

    console.log(1);   setTimeout(function(){
       console.log(2);
        new Promise((resolve,reject) =>{
            console.log(3);
            resolve();
            console.log(4)
        })
        .then(()=>{
            console.log(5)
        })     
   })
    
    console.log(6);


    /*
        
        第一步:发现事件 -> 开启event loop 事件循环机制 

        第二步:将同步任务console.log(1)放入event loop事件循环中  - >  [打印  1]
        第三步:发现宏任务且是异步 -> 将setTimeout放入event loop事件循环中,

                等到线程同步任务结束在开始执行    

        第四步:发现同步任务console.log(6),将同步任务console.log(6)放入event loop事件循环中 [打印6]
        第五步:setTimeout异步宏任务发现js线程同步任务结束,终于轮到我执行了吧,将setTimeout放入js线程

        第六步:执行setTimeout宏任务 首先发现同步任务 console.log(2)将其放入event loop事件循环机制中,

        第七步:发现同步微任务promise(),将promise()放入event loop 事件循环中
    
        第八步:进入promise()微任务 ,放入event loop事件循环中 ->  发现同步任务console.log(3) [打印3]
        
        第九步:发现resolve() ->  promise().then()  可以向下执行

        第十步:发现同步任务console.log(4),将其放入event loop事件循环中  [打印4]

        第十一步:同步任务执行完,执行微任务promise().then() ->  [打印  ->  5]

        第十二步:js 线程上没有任务,结束event loop 事件循环
        
        至此结束, 打印结果依次为[ 1 -> 6 -> 2 -> 3 -> 4 -> 5    ]
    */复制代码

至此,你明白了js event loop 事件循环了吗?


关注下面的标签,发现更多相似文章
评论