• js运行机制之微任务和宏任务


    • 宏任务队列可以有多个,微任务队列只有一个;
    • 主线程上的任务是第一个宏任务;
    • 会建立宏任务的有:setTimeOut、 setInterval、 requestAnimationFrame
    • 会建立微任务的有:Promise的回调、 process.nextTick
    • 当有一个宏任务队列执行完毕后,会执行微任务队列中的全部内容,然后执行另一个宏任务队列,如此反复

    js代码执行机制基本是这样的:当遇到3中的内容时建立新的宏任务,遇到4中的内容时将其加入微任务,然后按5中的顺序执行。结合下面的例子来分析一下:

    复制代码
    console.log("1")
    
    
    // setTimeOut函数不设置时间
    setTimeout ( () => {
        console.log('2')
        new Promise( (resolve => {
            console.log("3")
            resolve()
        })) .then ( () => console.log("4"))
    })
    
    
    new Promise ( (resolve, reject) => {
        console.log("5")
        resolve()
    }) .then( () => console.log('6'))
    
    
    setTimeout ( () => {
        console.log('7')
    })
    
    
    console.log("8")
    复制代码

    *测试发现setTimeOut不加时间与设置时间为0效果相同,都是等主线程上的代码执行完后立即执行

    分析:

    js代码从上到下执行,先遇到console.log(1),将其加入主线程的宏任务队列,然后发现setTimeOut,为其创建第二个宏任务队列并将其加入,其中代码先不执行,然后遇到Promise,将其中的console.log(5)加入主线程的宏任务队列,将then回调函数中的内容加入微任务队列,继续往下发现第二个setTimeOut,将其放入第三个宏任务队列,最后将console.log(8)放入主线程宏任务队列,到此,代码已经完成了在不同队列中的分布,详细情况为:

    接下来开始执行第一个宏任务队列,分别打印1,5,8,然后执行微任务队列,打印6,微任务队列变为空。接着执行第二个宏任务队列,开始执行第一个setTimeOut中的代码:先后打印 2,3,并将回调函数中的console.log(4)加入微任务。此时第二个宏任务队列执行完毕,开始执行微任务队列,打印 4。接着执行第三个宏任务队列,打印 7。执行完毕。所以最终输出顺序为:15862347。

  • 相关阅读:
    让人耗尽脑汁的需求分析工作
    解读ASP.NET 5 & MVC6系列(1):ASP.NET 5简介
    WCF序列化与反序列化问题
    SQL存储过程调试
    MSSQL CharIndex()用法
    Erp:原料投入产出报表
    union all 简单用法
    带有游标的应用的存储过程
    SQL批量删除与批量插入
    表与表 不同条件下的关联SQL
  • 原文地址:https://www.cnblogs.com/crazycode2/p/12150548.html
Copyright © 2020-2023  润新知