首页 > 其他分享 > 事件循环机制(面试快速解题技巧)

事件循环机制(面试快速解题技巧)

时间:2022-12-20 19:57:39浏览次数:65  
标签:异步 resolve console log 面试 任务 循环 流水线 解题技巧

目录

事件循环机制

同步与异步

我们先思考两个问题,如下:

为什么会存在同步和异步的概念?

我们的JavaScript是单线程的,也就是我们的工作流水线的只有一条。如果我们的任务全放在流水线上,其中一个任务出现问题就会阻塞后面的任务,导致我们的工作流水线卡住。因此为了更加高效合理利用这条流水线,在JavaScript中出现了同步与异步的概念。

同步与异步任务如何在一条流水线上工作?

同样是一条流水线。我们的有不同的产品,有的产品能瞬间完成,有的产品需要耗费大量时间才能完成。那么我们给这堆产品分为两类,能瞬间完成的产品先放入流水线前面,而需要耗费大量时间的产品则放在流水线后面。将所有的产品按顺序从流水线上执行。即使后面有部分产品制作很慢,但我们流水线前面的大部分产品都能顺利完成。也就是说,我们能够及时交付大部分的产品,让老板基本满意就足够了。后面的产品我们再慢慢做也不迟。

同步

同步任务:我们的任务不会造成流水线阻塞,瞬间就能完成。那我们直接把这些任务定义为同步任务。

同步事件:new Promise()、async关键字、console对象方法

异步

异步任务:我们的任务可能会造成流水线阻塞,需要时间才能完成。那我们直接把这些任务定义为异步任务。

异步事件:我们先不介绍异步事件,因为异步事件又分为微任务与宏任务。我们下面再介绍。

微任务与宏任务(异步事件)

微任务事件:Promise.then()、await 后面的语句、queueMiscrotask、MutationObserver、process.nextTick( node.js环境 )[ 微任务中最先执行 ]

宏任务事件:setTimout() 和 setInterval()、<script>脚本、I/O、UI交互事件、setImmediate( node.js环境 )[ 宏任务中最后执行 ]

注意:异步事件分为微任务和宏任务,其中微任务优先于宏任务执行。

任务执行顺序

执行栈:同步代码会首先归类到此处待执行。按照代码的书写顺序(上到下)入栈。

微任务队列:异步中的微任务代码归类到此处。按照代码的书写顺序(上到下)入队。当执行栈为空时,微任务会出队进入执行栈

宏任务队列:异步中的宏任务代码归类到此处。按照代码的书写顺序(上到下)入队。当微任务队列为空时,宏任务会出队进入执行栈

我们采用验证法做几道题

第一道如下

console.log(1)
setTimeout(() => {
    console.log(2)
    setTimeout(() => {
        console.log(3)
    }, 1000)
}, 1000)
new Promise((resolve, reject) => {
    console.log(4)
    resolve(5) // 之后会调用 then 方法
    console.log(6)
}).then((resolve, reject) => {
    console.log(resolve)
})
function add(a, b) {
    return a + b
}
async function foo() {
    console.log(7)
    let num = await add(4, 4)
    console.log(9)
    return num
}
foo().then((num) => {
    console.log(num)
})
console.log(10) // 1 4 6 7 10 5 9 8 2 3

以上代码没有出现宏任务嵌套微任务,微任务嵌套宏任务的情况。那么我们可以按编号(对应的输出语句)直接对执行栈、微任务和宏任务分类如下:

第一次分析执行栈(同步任务):1 4 6 7 10

第二次分析微任务:5 9 8

第三次分析宏任务:2 3

然后我们按执行顺序将答案组合在一起。最终答案:1 4 6 7 10 5 9 8 2 3。

注意:以上分析方法只能应对异步函数无嵌套的情况。

接下来我们增加难度,宏任务嵌套微任务,微任务嵌套宏任务第二题如下

console.log(1)
setTimeout(() => {
    console.log(2)
    new Promise((resolve, reject) => {
        console.log(3)
      	resolve(4)
    }).then((resolve, reject) => {
        console.log(resolve)
    })
  	console.log(5)
}, 1000)
console.log(6)
new Promise((resolve, reject) => {
    console.log(7)
    resolve(8)
    setTimeout(() => {
        console.log(9)
    }, 1000)
}).then((resolve, reject) => {
    console.log(resolve)
})
console.log(10) // 1 6 7 10 8 2 3 5 4 9

以上代码出现了宏任务嵌套微任务,微任务嵌套宏任务的情况。

提示:外部(全局作用域)的代码可以按任务执行顺序分析,异步函数内部其实也可以按照我们的任务执行顺序分析。其分析过程是一样的。

最终答案:1 6 7 10 8 2 3 5 4 9。还有很多特例,可自行编写异步函数测试。总结方法

最终总结

分析方法:先对代码进行事件分类,然后分别放入对应类型的三个地方(执行栈、微任务队列和宏任务队列)再按照我们的执行顺序,发生异步函数嵌套情况时,也可以对其内部应用这套规则解决。

任务执行顺序如下

  1. 同步(new Promise()、async关键字、console对象方法)
  2. process.nextTick(node.js环境)
  3. 微任务(异步)(Promise().then()、await 后面的语句)
  4. 宏任务(异步)(定时器函数、<script>脚本、I/O、UI交互事件)
  5. setImmediate(node.js环境)(当前事件循环结束后执行)

参考

【前端八股文】事件循环-宏任务和微任务

标签:异步,resolve,console,log,面试,任务,循环,流水线,解题技巧
From: https://www.cnblogs.com/chscript/p/16994963.html

相关文章

  • 王爽 汇编语言第三版 问题 7.9 将 datasg 段中前4个字母变成大写(汇编中的双重循环)
      问题7.9:将datasg段中前4个字母变成大写 汇编代码:assumecs:codesg,ss:stacksg,ds:datasgstacksgsegmentdb0,0,0,0,0,0,0,0stacksgendsdatasgsegment......
  • 关于字典的几种循环
    #关于字典的几种循环scores={'zhangsan':98,'lisi':89,'maishu':96}#方法一:fornameinscores:print(f'{name}:{scores[name]}')#默认情况下,循环字典,......
  • 从面试题入手,畅谈 Vue 3 性能优化
    前言今年又是一个非常寒冷的冬天,很多公司都开始人员精简。市场从来不缺前端,但对高级前端的需求还是特别强烈的。一些大厂的面试官为了区分候选人对前端领域能力的深度,经常......
  • 商汤科技面试
    1.cpu缓存用于减少处理器访问内存所需平均时间的部件。其容量远小于内存,但速度却可以接近处理器的频率。当处理器发出内存访问请求时,会先查看缓存内是否有请求数......
  • 史上最全软件测试工程师常见的面试题总结(一)【多测师】
    1、jmeter的加密参数如何入参?  ==》通过beanshell脚本处理、然后通过变量形式去接受2、如果不是MD5,怎么实现加密参数入参  ==》通过AESRSA等等加密算法3、给你一个......
  • 面试官:MySQL一千万数据,怎么快速查询?
    前言面试官:来说说,一千万的数据,你是怎么查询的?me:直接分页查询,使用limit分页。面试官:有实操过吗?me:肯定有呀此刻献上一首《凉凉》也许有些人没遇过上千万数据量的表,也不清楚查......
  • 校招前端二面高频vue面试题(边面边更)
    Vue中封装的数组方法有哪些,其如何实现页面更新在Vue中,对响应式处理利用的是Object.defineProperty对数据进行拦截,而这个方法并不能监听到数组内部变化,数组长度变化,数组的......
  • 前端一面必会react面试题(附答案)
    前言:最近接触到一种新的(对我个人而言)状态管理方式,它没有采用现有的开源库,如redux、mobx等,也没有使用传统的useContext,而是用useState+useEffect写了一个发布订阅者模式进......
  • 社招前端一面必会react面试题集锦
    vue或者react优化整体优化虚拟dom为什么虚拟dom会提高性能?(必考)虚拟dom相当于在js和真实dom中间加了一个缓存,利用domdiff算法避免了没有必要的dom操......
  • Python面试常见算法题集锦(递归部分)
    0x1前言开始学习python基础的时候,有以下几种算法是面试中常见的,也是前期学习python的时候可以连带学习了解的,不卡门槛哟0x2实现算法的方式很多种,而算法的实现也是分程......