前端面试常考 | 事件循环-eventloop



一. 前言

事件循环-eventloop前端笔试中的高频考点,了解事件循环也可以更好的理解代码底层运行机制,夯实基本功,比如下面这一段代码:

console.log(1);
setTimeout(function () {
    console.log(2);
}, 2000);
console.log(3);
// 输出结果 1 3 2

输出的结果毫无疑问: 1 3 2
那么下面一段代码呢?

console.log(1);
setTimeout(function () {
   console.log(2);
}, 0);
console.log(3);
// 输出结果 1 3 2

输出的结果还是 : 1 3 2 ,那么这是为什么呢?

二. 同步与异步

众所周知jS是单线程的,也就是说,事情只能一件一件的做,但是有些任务是耗时的,会阻塞代码的执行,为了解决这个问题,我们有了同步异步的概念。
这样我们就可以把代码分为同步代码(同步任务)和异步代码(异步任务),比如上面的例子我们可以向下面这样拆分:

// 同步代码
console.log(1);
console.log(3);
// 异步代码
setTimeout(function () {
    console.log(2);
}, 2000);

同步代码:立即放入JS引擎(JS主线程)执行,并原地等待结果。
异步代码:先放入宿主环境(浏览器/Node),不必原地等待结果,并不阻塞主线程继续往下执行,异步结果在将来执行。
所以输出的顺序是 1 3 2
执行过程:
同步代码放到执行栈中立即执行,而异步代码先会存放到宿主环境中,当达到触发条件后,就会将这个异步任务推送给任务队列(推送回调函数),当执行栈执行完毕后就会去任务队列中拉取其中的任务进行执行,这个去任务队列中拉取异步任务的过程就是事件循环
常见的异步任务:
除了,setTimeout,常见的异步代码还有 setInterval、Ajax/Fetch、事件绑定、promise里面then和catchl,他大致的共同点就是都是耗时的。

三. 宏任务与微任务

通过上一章的讲解,我们可以把代码分为同步代码(同步任务)和异步任务(异步任务),而在JS中我们又可以把异步任务分为宏任务微任务,在ES5之后,JavaScript引入了Promise,这样,不需要浏览器,JavaScripti引擎自身也能够发起异步任务了。
宏任务是由宿主(浏览器、Node)发起:

任务(代码)任务类型环境
script宏任务浏览器
事件宏任务浏览器
网络请求(Ajax/Fetch)宏任务浏览器
setTimeout和setInterval(定时器)宏任务浏览器

微任务JS引擎发起的任务:

任务(代码)任务类型环境
Promise微任务JS引擎

值得注意的是:Promise本身同步,then/catch的回调函数是异步的。
那么代码的类型就可以细分为三类:

  • 同步代码(JS执行栈/回调栈)
  • 微任务的异步代码(JS引擎),常见的有 process.nextTick、Promise.then()catch()、Async/Await、Object.observe 等等
  • 宏任务的异步代码(宿主环境),script(代码块)、setTimeout/setinterval定时器、setlmmediate定时器

执行过程:
同步代码放到执行栈中立即执行,异步任务分为宏任务与微任务分别存放到宏任务队列微任务队列,执行栈中的同步代码执行完毕后,去微任务队列中拉取微任务放到执行栈中执行(先进先出原则),微任务队列中的任务执行完毕后,再去宏任务队列(先进先出)中拉取任务到执行栈中执行,直达执行完毕。
例如下面的例子:

console.log(1);
setTimeout(function () {
    console.log(2);
}, 0);
const p = new Promise((resolve, reject) => {
    console.log(3);
    resolve(1000) // 标记成功 
    console.log(4);
})
p.then(data => {
     console.log(data);
})
console.log(5);

执行栈同步任务:

console.log(1);
console.log(3);
console.log(4);
console.log(5);

微任务队列:

data => {
     console.log(data);
}

宏任务同步队列:

function () {
    console.log(2);
}

所以最后的执行结果是: 1 3 4 5 1000 2

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值