浏览器 任务队列、事件循环,微任务和宏任务

參考文章:https://segmentfault.com/a/1190000016278115
参考文章
1.任务队列与循环事件
任务队列(消息队列)可以存放要执行的任务。它符合队列“先进先出”的特点。 在任务队列中,其实还分为宏任务队列(Task Queue)微任务队列(Microtask Queue),对应的里面存放的就是宏任务和微任务。宏任务和微任务都是异步任务。
2、事件循环系统
监听并执行消息队列中的任务
在这里插入图片描述

事件循环 Event Loop是一种事件执行机制。 JavaScript语言就采用这种机制,来解决单线程运行带来的一些问题
宏队列和微队列
宏队列,macrotask,也叫tasks。 一些异步任务的回调会依次进入宏队列 macro task queue,等待后续被调用,浏览器异步任务宏任务包括:比如: script(整体代码) 定时器回调、DOM 事件回调、ajax 回调
setTimeout
setInterval
UI rendering

微队列,microtask,也叫jobs。 另一些异步任务的回调会依次进入微队列 micro task queue,等待后续被调用,这些异步任务微任务包括:promise的回调、MutationObserver 的回调
Promise
Object.observe

JS 执行时会区别这 2 个队列
JS 引擎首先必须先执行所有的初始化同步任务代码
每次准备取出第一个宏任务执行前, 都要将所有的微任务一个一个取出来执行,也就是优先级比宏任务高,且与微任务所处的代码位置无关
Promise定义之后便会立即执行,其后的.then()是异步里面的微任务。

    //script start
    //as1 start
    //as2
    //prom1
    //script end
    //as1 end
    //prom2
    //setTimeOut1
    //setTimeOut2
    //一段代码执行时,会先执行宏任务中的同步代码:如果执行中遇到 setTimeout 之类宏任务,那么就把这个 setTimeout 推入「宏任务的队列」中,下一轮宏任务执行。
    //第一个宏任务: console.log('script start')
    // setTimeOut 推入「宏任务的队列」中
    // 第一个微任务 as1 start
    //在第一个微任务中存在await关键字,得到await右侧表达式的结果 as2 ,await会阻塞后面的代码执行,因此跳出async函数执行下一个微任务
    //下一个微任务 console.log('prom1')
    //碰到promise.then这个微任务会先执行本轮宏任务的同步代码 console.log('script end') 再执行微任务,先进先出  as1 end prom2
    //下一轮宏任务 ,先进先出
    // setTimeOut1 setTimeOut2
    setTimeout(() => {
        console.log('setTimeOut1')
    }, 0)
    async function as1(params) {
        console.log('as1 start')
        await as2()
        console.log('as1 end')
    }
    async function as2(params) {
        console.log('as2')
    }
    console.log('script start')
    setTimeout(() => {
        console.log('setTimeOut2')
    }, 0)
    as1()
    new Promise((resolve, reject) => {
        console.log('prom1')
        resolve()
    }).then(() => {
        console.log('prom2')
    })
    console.log('script end')
    //3 7 4 1 2 5
    //宏 5
    //微 3 7 4 1 2
    const first = () => (new Promise((resolve, reject) => {
        console.log(3)
        let p = new Promise((resolve, reject) => {
            console.log(7)
            setTimeout(() => {
                console.log(5)
                resolve(6) //会被忽略,因为会先执行微队列里的resolve(1),此时状态已经改变过了,且状态只能改变一次
            }, 0)
            resolve(1)
        })
        resolve(2)
        p.then((arg) => {
            console.log(arg + '1---')
        })
    }))

    first().then((arg) => {
        console.log(arg + '2xxx')
    })
    console.log(4)
    //宏任务 0
    //微任务 1 7  2 3 8 4  6 5 
    //1 7  2 3 8 4  6 5 0 
    setTimeout(() => {
        console.log("0")
    }, 0)
    new Promise((resolve, reject) => {
        console.log("1")
        resolve()
    }).then(() => {
        console.log("2")
        new Promise((resolve, reject) => {
            console.log("3")
            resolve()
        }).then(() => {
            console.log("4")
        }).then(() => {
            console.log("5")
        })
    }).then(() => {
        console.log("6")
    })

    new Promise((resolve, reject) => {
        console.log("7")
        resolve()
    }).then(() => {
        console.log("8")
    })


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值