美文网首页
什么是Event Loop

什么是Event Loop

作者: 被代码耽误的裁缝 | 来源:发表于2019-07-08 15:34 被阅读0次

    Event Loop

    一、进程和线程

    1.进程:

    资源分配的最小单位;应用程序的执行实例,每一个进程都是由私有的虚拟地址空间、代码、数据和其他系统资源所组成;进程拥有独立的堆栈空间和数据段,每当启动一个新的进程必须分配给他独立的地址空间,建立众多的数据表来维护它的代码段、堆栈段和数据段。

    2.线程:

    程序执行的最小单位;线程是进程内的一个独立执行单元,在不同的线程之间是可以共享进程资源的;

    线程拥有独立的堆栈空间,但是共享数据段,他们彼此之间使用相同的地址空间,共享大部分数据,比进程更节俭,开销比较小,切换速度也比进程快,效率高。

    二、同步任务和异步任务

    我可以将任务分为同步任务和异步任务,但是这并不准确。

    1.同步任务:

    同步任务就是在主线程上排队执行的任务,只能执行完一个再执行下一个。

    2.异步任务:

    异步任务则不进入主线程,而是现在 event table 中注册函数,当满足触发条件后,才可以进入任务队列来执行。只有任务队列通知主线程说,我这边异步任务可以执行了,这个时候此任务才会进入主线程执行。

    3.举例

    console.log("a");
    setTimeout(function(){
        console.log("b")
    },1000)
    console.log("c")
    
    //"a" "c" "b"
    /*
        1.console.log("a")是同步任务,进入主线程执行,打印"a"
        2.setTimeout 是异步任务,先被放入 event table 中注册,1000ms 之后进入任务队列
        3.console.log("c")是同步任务,进入主线程执行,打印"c"
        当"a","c"被打印后,主线程去事件队列中找到 setTimeout 里的函数,并执行,打印"b"
    */
    

    三、宏任务和微任务

    同步任务和异步任务的划分其实并不准确,准确的分类方式是宏任务(Macrotask)和微任务(Microtask)。

    1.宏任务

    宏任务包括:script(整体代码)、setTimeout、setInterval、setImmediate、I/O、UI rendering。

    2.微任务

    微任务包括:process.nextTick、Promise、MutationObserver(html5新特性)。

    这种分类的执行方式就是,执行一个宏任务,过程中遇到微任务时,将其放到微任务的事件队列里,当前宏任务执行完后,会查看微任务的事件队列,依次执行里面的微任务。如果还有宏任务的话,再重新开启宏任务…

    通俗的可以理解为,首先执行script(整体代码)宏任务,从上往下执行,遇到宏任务放入宏任务队列,遇到微任务放入微任务队列 => 执行微任务队列的任务,然后执行宏任务队列的第一个任务

    =>执行script(整体代码)宏任务,从上往下执行,遇到宏任务放入宏任务队列,遇到微任务放入微任务队列
    =>查看微任务队列并执行
    =>执行宏任务队列的第一个任务
    =>查看微任务队列并执行
    =>执行宏任务队列的第二个任务
    =>查看微任务队列并执行
    =>执行宏任务队列的第三个任务
    =>查看微任务队列并执行
    ....
    

    3.举例

    setTimeout(function(){
        console.log("a")
    })
    new Promise(function(resolve){
        console.log("b")
        for(var i=0;i<10000;i++){
            i==99 && resolve();
        }
    }).then(function(){
        console.log("c")
    })
    console.log("d")
    //"b" "d" "c" "a"
    /*
        1.首先执行 script 下的宏任务,遇到 setTimeout,将其放入宏任务的队列里
        2.遇到 Promise,new Promise 直接执行,打印"b"
        3.遇到 resolve=>then 方法,是微任务,将其放入微任务的队列里
        4.遇到 console.log("d"),直接打印"d"
        5.本轮宏任务执行完毕,查看微任务,发现 then 方法里的函数,打印"c"
        6.本轮 event loop 全部完成
        7.下一轮循环,先执行宏任务,发现宏任务队列中有一个 setTimeout,打印"a"
    */
    
    console.log("a")
    setTimeout(function(){
        console.log("b")
        process.nextTick(function(){
            console.log("c")
        })
        new Promise(function(resolve){
            console.log("d")
            resolve();//如果没有执行 resolve,那么 then 方法不执行
        }).then(function(){
            console.log("e")
        })
    })
    process.nextTick(function(){
        console.log("f")
    })
    new Promise(function(resolve){
        console.log("g")
        resolve()//如果没有执行 resolve,那么 then 方法不执行
    }).then(function(){
        console.log("h")
    })
    setTimeout(function(){
        console.log("i")
        process.nextTick(function(){
            console.log("j")
        })
        new Promise(function(resolve){
            console.log("k")
            resolve()
        }).then(function(){
            console.log("l")
        })
    })
    //"a" "g" "f" "h" "b" "d" "i" "k" "c" "j" "e" "l"
    //第一轮宏任务打印:"a" "g"
    //第一轮微任务打印:"f" "h"
    //第二轮宏任务打印:"b" "d" 
    //第二轮微任务打印:"c" "e"
    //第三轮宏任务打印:"i" "k"
    //第三轮微任务打印:"j" "l"
    
    console.log("script start")
    setTimeout(function () {
        console.log("a")
        setTimeout(function () {
            console.log("b")
        })
        new Promise(function (resolve) {
            console.log("c")
            resolve();
        }).then(function () {
            console.log("d")
            setTimeout(function () {
                console.log("e")
            })
        })
    })
    new Promise(function (resolve) {
        console.log("f")
        resolve()
    }).then(function () {
        console.log("g")
    })
    setTimeout(function () {
        console.log("h")
        setTimeout(function () {
            console.log("i")
        })
        new Promise(function (resolve) {
            console.log("j")
            resolve();
        }).then(function () {
            console.log("k")
            setTimeout(function () {
                console.log("l")
                new Promise(function (resolve) {
                    console.log("m")
                    resolve()
                }).then(function () {
                    console.log("n")
                    setTimeout(function () {
                        console.log("o")
                    })
                })
            })
        })
    })
    //执行一个宏任务,检查并执行微任务队列
    
    //最终打印顺序为: 
    //"script start" "f" "g" "a" "c" "h" "j" "k" "b" "e" "i" "l" "m" "n" "o"
    

    相关文章

      网友评论

          本文标题:什么是Event Loop

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