JS 的特色就是异步编程,所有有很多关于异步的考点,本章都会讲解。如 event loop、promise、async-await、微任务和宏任务。学不会这些,就不算是精通 JS ,也无法进大厂。
一、event loop(事件循环/事件轮询)
过程1:
- 同步代码,一行 一行放在Call stack执行
- 遇到异步,会先“记录”下,等待时机(定时、网络请求等)
- 时机到了,就移动到Callback Queue
过程2:
- 如果 Call Stack为空(即同步代码执行完)Event Loop开始工作
- 轮询查找Callback Queue,如有则移动到Call Stack执行
- 然后继续轮询查找(永动机一样)
下面是一个流程展示实例:
1、首先打印‘Hi’,放入调用栈
2、清空调用栈,再把setTimeout放入调用栈
3、在Web APIS记录定时器任务,等待执行
4、清空调用栈,把下一行代码放入调用栈中。
5、调用栈空闲时,启动event loop 机制。
6、定时器任务开始执行,放入Callback Queue队列中
7、由event loop把Callback Queue队列中的内容逐个放入Call Stack中执行
8、执行cb1函数体内代码
DOM事件和event loop的相关性:
- JS是单线程的
- 异步(setTimeoout、setInterval、ajax等)使用回调,是基于event loop
- DOM事件也使用回调,是基于event loop
二、Promise 进阶
1、Promise 三种状态
分别是:pending、resolved、rejected
- pending -> resolved 或 pending -> rejected
- 变化不可逆
2、函数then和函数catch触发状态的影响
- pending状态,不会出发then和catch
- resolved状态,会出发后续的then回调函数
- rejected状态,会出发后续的catch回调函数
3、函数then和函数catch改变状态
- then正常返回resolved状态,里面有报错则返回rejected状态呢。
- catch正常返回resolved状态,里面有报错则返回rejected状态。
4、async/await
- 同步代码解决了异步回调,是一个很香的语法糖
- async/await 和 Promise是相辅相成的
为什么两者是相辅相成的关系?
- 执行async函数,返回的是Promise对象
- await 相当于Promise的then函数
- try...catch,代替了Promise的catch函数
三、微任务(micro Task)和宏任务(macro Task)
1、微任务有哪些?宏任务有哪些? 微任务触发时机更早 微任务: Promise async/await 宏任务: setTimeout,setInterval,Ajax,DOM事件
2、微任务、宏任务和DOM渲染的关系
微任务在DOM渲染之前执行,宏任务是在DOM渲染之后执行。
3、DOM渲染,在event loop的过程
JS是单线程的,所以跟DOM渲染共用一个线程。JS执行的时候,得留一些时机供DOM渲染。每次Call Stack清空(即每次轮询结束),同步任务执行完。都是DOM重新渲染的机会,DOM结构如有改变则重新渲染。然后再去触发下一次Event Loop。