js的eventloop中的宏任务和微任务理解,实现对setTimout定时器补偿

js的eventloop中的宏任务和微任务理解,实现对setTimout定时器补偿

写有关宏任务和微任务的优秀博文有很多已经差不多讲的很详细,写这边博客并不是要做一个补充, 大略只是对自己学习理解做一个记录补充,同时进行分享。有助于输出推动学习。

外文链接:https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/?utm_source=html5weekly

event loop(事件循环)

我们js运行是单线程的,所以js的执行事件就需要按照顺序排列一项一项执行任务,当执行完成这次的之后就会等待下一次事件队列执行,如此循环往复就叫 eventLoop

同步&异步任务执行顺序

我们都知道js的代码运行分为同步和异步,同步代码不会等待异步代码执行完毕,而是先执行同步代码后执行异步代码。直接看图:(网上素材)
在这里插入图片描述
解释一下:

1.当一个一个事件循环开始时,同步事件直接放到主线程执行,异步事件放到event table并回调事件, 异步事件执行玩之后需要调用回调的时候,就到event queue中等待真正执行。

2.事件处理机制读取主线程任务并执行完毕。

3.之后从event queue中读取回调到主线程的事件执行

也就是说,当异步事件执行完之后回调并不是立即执行的,而是要等待主线程同步任务执行完毕

所以当我们使用setTimeout作为定时器时,经常会不精确,因为有可能主线程需要运算很久的话,定时器的回调就会一直等待同步代码执行完毕

function func() {
	setTimeout(()=> {
		console.log("异步")
	},100)
	/*
		一段需要大量计算的同步代码... (耗时3s)
	*/
	console.log("同步")
}

//控制台
同步
异步

这对于抽奖这种需要时间很准确的场景来说,就显得很严重了,所以我们尝试通过定时器补偿的方法来提高精确度

let start = new Date().getTime(),  
    time = 0,  
    before = '0.0';  
function instance()  
{  
    time += 100;  
    before = Math.floor(time / 100) / 10;  
    if(Math.round(before) == before) { before += '.0'; }  
    document.title = before;  
    var diff = (new Date().getTime() - start) - time;  
    setTimeout(instance, (100 - diff));  
}  
setTimeout(instance, 100);  

宏任务&微任务

宏任务和微任务都是异步执行的事件,但是又分执行先后。

宏任务主要包括: 执行script代码块,setTimeout,setInterval、setImmediate。

微任务包括: 原生Promise、process.nextTick、Object.observe、 MutationObserver

其中我们最常见的就是 setTimeout,setInterval,Promise这几个

//代码
console.log('script start');

setTimeout(function() {
  console.log('setTimeout');
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');

//输出
script start
script end
promise1
promise2
setTimeout

从上面我们可以看出执行顺序是:

同步任务 => Promise回调(微任务) => setTimeout(宏任务)

但是其实真正的执行顺序是宏任务先被放到event Table中注册执行,微任务后被放到event Table中注册执行,但是最后主线程是从event Queue先取出微服务的回调执行,宏服务的回调后执行。

如图:(网上素材)
在这里插入图片描述

总来的来说了解event loop事件循环处理机制还是很有必要的,让我们了解为什么代码是这样执行的,可以避免不必要的错误。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值