js异步之宏任务(marcroTask)和微任务(microTask)

什么是宏任务和微任务

  • 宏任务: setTimeout,setInterval,Ajax,DOM事件
  • 微任务:Promise async await
  • 微任务执行时机比宏任务要早

异步和单线程

异步和单线程是相辅相成的,js是一门单线程脚本语言,所以需要异步来辅助

异步和同步的区别:

  • 异步不会阻塞程序的执行,
  • 同步会阻塞程序的执行,

前端使用异步的场景:

  • 定时任务:setTimeout,setInverval
  • 网络请求:ajax请求,动态img加载
  • 事件绑定
//ajax请求代码示例
console.log('start')
$.get('./data1.json',function(data1){
	console.log(data1)
})
console.log('end')

img加载示例:

       console.log('start');
       var img=document.createElement('img')
       img.onload=function(){
           console.log('loaded');
       }
       img.src='/xxx.png'
       console.log('end');

事件绑定示例:

  console.log('start');
        document.getElementById('btn1').addEventListener('click', function () {
            alert('clicked')
        })
        console.log('end');

也就是请求处理过程中,你不能闲着,会产生异步的请求,回头再处理,然后继续执行下面的请求

同步异步问题

首先,你要知道javascript是单线程语言。js任务需要排队顺序执行,如果一个任务耗时过长,后边一个任务也的等着,但是,假如我们需要浏览新闻,但新闻包含的超清图片加载很慢,总不能网页一直卡着直到图片完全出来,所以将任务设计成了两类:

同步任务
异步任务

同步和异步任务分别进入不同的执行“场所”,同步进入主线程,异步进入Event Table并注册函数。当指定的事情完成时,Event Table会将这个函数移入任务队列(Event Queue)。主线程内的任务执行完毕为空,就去任务队列(Event Queue)读取对应的函数,进入主线程执行。

上述过程会不断重复,也就是常说的Event Loop(事件循环)。

但是,JS异步还有一个机制,就是遇到宏任务,先执行宏任务,将宏任务放入任务队列(event queue),然后再执行微任务,将微任务放入微任务队列(micro task queue),但是,这两个queue不是一个queue。当你往外拿的时候先从微任务队列里拿这个回调函数,然后再从宏任务的queue拿宏任务的回调函数

任务列队和event loop(事件循环)

单线程就意味着,所有的任务都要排队,前一个结束,才会执行后面的任务。如果列队是因为计算量大,CPU忙不过来,倒也算了。但是更多的时候,CPU是闲置的,因为IO设备处理得很慢,例如
ajax读取网络数据。js设计者便想到,主线程完全可以不管IO设备,将其挂起,然后执行后面的任务。等后面的任务结束掉,在反过头来处理挂起的任务。

执行顺序

1.主线程上宏任务、微任务执行顺序

console.log('---start---');//第一轮主线程
 
setTimeout(() => {
  console.log('setTimeout');  // 将回调代码放入个宏任务队列,第二轮宏任务执行
}, 0);
 
new Promise((resolve, reject) => {
  console.log('---Promise第一轮微任务同步执行---');//第一轮微任务同步执行
  resolve()
}).then(()=>{
  console.log('Promise.then实例成功回调执行'); // 将回调代码放入微任务队列,第一轮宏任务执行完后立即执行
});
 
console.log('---end---');//第一轮主线程结束

在这里插入图片描述
2.宏任务中包含微任务

// 宏任务队列 1
setTimeout(() => {
  // 宏任务队列 2.1
  console.log('timer_1');
  setTimeout(() => {
    // 宏任务队列 3
    console.log('timer_3')
  }, 0)
  new Promise(resolve => {
    resolve()
    console.log('new promise')
  }).then(() => {
    // 微任务队列 1
    console.log('promise then')
  })
}, 0)
 
setTimeout(() => {
  // 宏任务队列 2.2
  console.log('timer_2')
}, 0)
console.log('========== Sync queue ==========')


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值