javascript中的异步 macrotask 和 microtask

什么是macrotask?什么是microtask?
在理解什么是macrotask?什么是microtask之前,我们先来看看javascript中的事件循环机制,先看如下面一段代码:

console.log(1);
setTimeout(function(){
  console.log(2);
}, 0);
console.log(3);

很明显 上面运行的结果是 1,3,2;
上面代码 setTimeout的延时为0,可以理解为setTimeout为异步函数调用,这是因为javascript是单线程的,主线程拥有一个执行栈以及一个任务队列
,主线程会依次执行代码,当遇到异步函数时候,会先将该函数入栈,所有主线程函数运行完毕后再将异步函数出栈,直到所有的异步函数执行完毕即可。

Macrotasks和Microtasks

Macrotasks和Microtasks 都属于上述的异步任务中的一种,他们分别有如下API:
macrotasks: setTimeout, setInterval, setImmediate, I/O, UI rendering
microtasks: process.nextTick, Promise, MutationObserver

setTimeout的macrotask, 和 Promise的microtask 有哪些不同,先来看下代码如下:

复制代码

console.log(1);
setTimeout(function(){
  console.log(2);
}, 0);
Promise.resolve().then(function(){
  console.log(3);
}).then(function(){
  console.log(4);
});

复制代码

上面的代码输出的是 1, 3, 4, 2;

如上代码可以看到,Promise的函数代码的异步任务会优先于setTimeout的延时为0的任务先执行。
原因是任务队列分为 macrotasks 和 microtasks, 而promise中的then方法的函数会被推入到microtasks队列中,而setTimeout函数会被推入到macrotasks
任务队列中,在每一次事件循环中,macrotask只会提取一个执行,而microtask会一直提取,直到microsoft队列为空为止。
也就是说如果某个microtask任务被推入到执行中,那么当主线程任务执行完成后,会循环调用该队列任务中的下一个任务来执行,直到该任务队列到最后一个任务为止。而事件循环每次只会入栈一个macrotask,主线程执行完成该任务后又会检查microtasks队列并完成里面的所有任务后再执行macrotask的任务。

 

 

具体原理和扩展详见博客:

https://segmentfault.com/a/1190000014284857

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值