JavaScript 异步之宏队列与微队列

JavaScript 异步之宏队列与微队列

事件循环机制

事件循环的顺序,决定了JavaScript代码的执行顺序

宏任务:setTimeout, setInterval, setImmediate, I/O, UI rendering。
微任务: process.nextTick, Promise, MutationObserver(html5新特性)

浏览器

在这里插入图片描述
1.JS线程负责处理JS代码,当遇到一些异步操作的时候,则将这些异步事件移交给Web APIs 处理,自己则继续往下执行。
2.Web APIs线程将接收到的事件按照一定规则添加到任务队列中,宏事件(DOM事件、Ajax事件、setTimeout事件等)添加到宏任务队列中,微事件(Promise、nextTick)添加到微事件队列中。
3.JS线程处理完当前的所有任务以后(执行栈为空),它会先去微任务队列获取事件,并将微任务队列中的所有事件一件件执行完毕,直到微任务队列为空后再去宏任务队列中取出一个事件执行(每次取完一个宏任务队列中的事件执行完毕后,都先检查微任务队列)。
4.然后不断循环第3步。

补充:

  1. 浏览器标准环境中(比如说谷歌webkit内核),是一个宏任务紧接着所有微任务执行。
  2. 在node环境中,则又不一样了,是一个类型宏任务队列执行完,再去执行微任务。

宏队列与微队列

异步执行的函数(回调函数)放入队列中执行。队列分为宏队列与微队列。

宏队列:用来保存执行的宏任务(回调),比如:dom事件回调,ajax回调,定时器回调
微队列:用来保存执行的微任务(回调),比如:promise回调,mutation回调

在这里插入图片描述

1.JS为单线程引擎,必须先执行所有的初始化同步任务代码。
2.每次取出第一个宏任务执行前,都要将所有的微任务执行完毕。

同步->微队列->宏队列

 setTimeout(()=>{ //会立即放入宏队列
        console.log("timeout callback1()");
        Promise.resolve(3).then(
            value =>{ //会立即放入微队列
                console.log("Promise onResolved3()",value);
            }
        )
    },0)
    setTimeout(()=>{ //会立即放入宏队列
        console.log("timeout callback2()");
    },0)
    Promise.resolve(1).then(
        value =>{ //会立即放入微队列
            console.log("Promise onResolved1()",value);
        }
    )
    Promise.resolve(2).then(
        value =>{ //会立即放入微队列
            console.log("Promise onResolved2()",value);
        }
    )
 /*
  输出:Promise onResplved(),1
       Promise onResplved(),2
       timeout callback1()
       Promise onResolved3()
       timeout callback2()
)
*/

注:取到栈里执行,若有嵌套的情况如下列代码,执行第一个setTimeout回调时,把里面的微任务放入微队列,执行第二宏任务前,先将所有的微任务执行完毕。

promise、async-await、setTimeout的执行顺序

async 函数返回一个 Promise 对象,当函数执行的时候,一旦遇到 await 就会先返回,等到触发的异步操作完成,再接着执行函数体内后面的语句。

1.await是一个让出线程的标志,await后面的函数会先执行一遍,然后跳出整个async函数来执行后面js栈的代码。

2.async函数总是会返回一个Promise的实例,调用一个async函数时,可以理解为里边的代码都是处于new Promise中,所以是同步执行的而最后return的操作,则相当于在Promise中调用resolve。
3.async函数代码执行是同步的,结果返回(相当于then?)是异步的。
4.回来执行await后(相当于.then)执行了

async function async1(){
	console.log('async1 start')
	await async2()
	console.log('async1 end')
}
async function async2(){
	console.log('async2')
}
console.log('script start')
setTimeout(function(){
	console.log('setTimeout') 
},0)  
async1();
new Promise(function(resolve){
	console.log('promise1')
	resolve();
}).then(function(){
	console.log('promise2')
})
console.log('script end')
/*
script start
根据点2 console.log('async1 start')
根据点2、点3 console.log('async2') 返回值是promise,await相当于then获取成功的值,要异步!会放入为微队列中等待 await会让出线程,跳出async1继续往下执行
promise1
then是异步的异步的! console.log('promise2')放入微队列等待
script end 
async1 end 
promise2  
setTimeout
*/

await会等同步代码执行完,以及微任务队列清空之后,再执行awati之后的代码。 之后才轮到宏任务队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值