event loop(事件循环、事件轮询)的机制
- JS是单线程运行的
- 异步要基于回调来实现
- eventloop就是异步回调的实现原理
JS是怎么执行的 - 从前到后,一行一行执行
- 如果某一行执行报错,则停止下面代码的执行
- 先把同步代码执行完,再执行异步
event loop过程 - 同步代码,一行一行放在Call Stack执行
- 遇到异步,会先记录下,等待时机(定时,网络请求等)
- 时机到了,就移动到Callback Queue
- 如Call Stack为空(即同步代码执行完)Event loop开始工作
- 轮询查找Callback Queue,如有则移动到Call Stack执行
- 然后继续轮询查找(永动机一样)\
DOM和Event loop的关系
- JS是单线程
- 异步(setTimeOut,ajax等)使用回调,基于event loop
- DOM事件也使用回调,基于event loop,触发的时机不同,需要用户交互,比如点击时触发\
什么是宏任务和微任务
promise有哪三种状态
Promise的三种状态
-
三种状态
pending(等待中) resolved(成功) rejected(失败)
pengding -》resolved或者pending-》rejeccted
变化不可逆 -
状态的表现和变化
pending,不会触发then和catch
resolved,会触发后续的then回调函数
rejected,会触发后续的catch回调函数 -
then和catch对状态的影响
then正常返回resolved,里面有报错则返回rejected\
const p1 = Promise.resolve().then(()=>{
return 100
})
p1.then(() => {
console.log(123);
})
const p2 = Promise.resolve().then(() => {
throw new Error("then error")
})
//只会触发catch回调,456不会被打印出来
p2.then(() => {
console.log('456');
}).catch(err=>{
console.error('err100',err);
})
catch正常返回resolved,里面有报错则返回rejected
const p3= Promise.reject('my error').catch(err=>{
console.error(err);
})
p3.then(()=>{
console.log(100);//打印出来
})
const p4= Promise.reject('my error').catch(err=>{
throw new Error("then error")
})
p4.then(()=>{
console.log(200);//不会打印
}).catch(()=>{
console.log('err');
})
async/await
-
异步回调callback hell
-
Promise then catch链式调用,但也是基于回调函数
-
async、await是同步语法,彻底消灭回调函数
async/await和Promise的关系 -
执行async函数,返回的是Promise对象
-
await相当于Promise的then
-
try...catch可捕获异常,代替了Promise的catch async/await只是一个语法糖,消灭异步回调,但JS还是单线程,还是有异步,还是基于event loop
宏任务和微任务 -
宏任务:setTimeout,setinterval,Ajax,Dom事件
-
微任务:Promise async/await
-
微任务比宏任务执行的时机要早
微任务和宏任务的区别 -
宏任务:DOM渲染后触发
-
微任务:DOM渲染前触发
为什么微任务执行更早 -
微任务是ES6语法规定的
-
宏任务是由浏览器规定的