美文网首页
步遥——事件循环队列

步遥——事件循环队列

作者: 你还想好吗 | 来源:发表于2020-12-06 11:16 被阅读0次

           js由于处理浏览器事件的原因,所以它是一个单线程的处理机制。但是为了提高cpu的利用率,js在主线程之外,会把一些计算的任务分配给子任务。事件循环就是js处理多任务同时进行的一种机制。

           js维护着一个调用栈,一个消息队列,一个微任务队列 ,其中调用栈中是同步任务代码,当执行过程中,遇到了同步任务,就压入调用栈中,并立即执行该任务,执行完毕之后,就把该执行环境销毁。当遇到一个异步任务,会根据是宏任务还是微任务,将该任务中的回调压入到对应的队列中。比如setTimeout,setInterval,setImmediate,I/O,UI rendering,等都是宏任务,遇到这些任务,会将这些方法中的回调中的处理任务(回调函数内部的代码)压入到消息队列中,而如果遇到了promise,process.nextTick,这样的微任务,就会把这些函数的回调函数放入到微任务队列中(new promise中的参数是同步任务,只有.then中的才是异步任务)。

           当调用栈中的代码执行完毕之后,就会先去检查微任务队列,如果微任务队列中有任务,就将微任务队列中待执行的全部任务依次压入调用栈中执行,直到微任务队列中的代码被执行完毕,然后去检查宏任务队列,再将宏任务队列中的第一个任务压入到调用栈中进行执行,执行完第一个宏任务之后,再去检查调用栈中是否有未执行的代码,优先执行调用栈中的代码,执行完毕之后再优先检查微任务队列,依次执行完所有的微任务队列中的代码后再去检查宏任务队列,还是只取出宏任务队列中的第一个任务执行,执行完毕之后,再去检查执行栈中是否有待执行任务,然后是微任务队列,最后再是宏任务队列,依次无限循环下去。。。

            举个例子:

    var p = new Promise(resolve => {

        console.log(4);//同步先执行

        resolve(5)

        })

        function fun1(){

        console.log(1)

        }

        function fun2(){

        setTimeout(()=>{

        console.log(2)

        });

        fun1();

        console.log(3);

        p.then(resolved=>{

        console.log(resolved)

        }).then(()=>{

        console.log(6)

        })

        }

    setTimeout(() => {

        console.log(7)//宏任务先压入宏任务队列

    }, 0);

        fun2()//执行func2时又压入一个宏任务和2个微任务

        fun1()//同步任务,要优于以上两个宏任务和微任务,但是2个微任务的执行优先级高于2个宏任务

    输出:

    4

    1

    3

    1

    5

    6

    7

    2

            这就是js中的事件循环机制。了解了该循环处理事件的机制,就能很好的遇见代码的执行顺序,并再出现问题时根据执行的顺序定位对应的问题点。

    相关文章

      网友评论

          本文标题:步遥——事件循环队列

          本文链接:https://www.haomeiwen.com/subject/rrlowktx.html