任务执行顺序
javascript是单线程语言,代码中所有任务都要排队执行。根据执行先后顺序不同,将任务分为同步任务和异步任务,异步任务又分为宏任务和微任务,执行顺序依次为:
- 同步任务
- 微任务
- 宏任务
宏任务
- setTimeout
- setInterval
- Ajax
- DOM事件
微任务
- Promise对象的then、catch和finally(new一个对象的过程是同步任务)
- async/await
- nodejs中的nextTick
async/await
- 用同步代码实现异步的最终解决方案
- async和await必须配合使用
- await所在任务必须等待Promise对象的函数参数的函数体有resolve成功函数或者有reject失败之后通过catch捕获异常的过程后,await的任务才结束
- await之前执行的代码是同步代码
事件执行过程
- 同步任务进入主线程
- 异步任务进入Event Table并注册函数,将宏任务放到Event Quene任务队列,将微任务放到微任务队列
- 执行主线程同步任务
- 将微任务队列中的微任务放入到主线程中执行
- 将任务队列中的宏任务放到主线程中执行
以上过程不断循环执行的机制,即事件循环机制
示例代码
setTimeout(() => {
console.log('1')
}, 0)
async function getUser() {
await new Promise((resolve, reject) => {
reject('2')
console.log('3')
}).catch((value) => {
console.log(value)
setTimeout(async () => {
console.log('4')
await new Promise((resolve, reject) => {
reject('5')
console.log('6')
}).catch((value) => {
console.log(value)
setTimeout(() => {
console.log('7')
}, 0)
})
console.log('8')
setTimeout(() => {
console.log('end')
}, 0)
}, 0)
})
console.log('9')
setTimeout(() => {
console.log('10')
}, 0)
}
async function getUser1() {
await new Promise((resolve, reject) => {
reject('11')
console.log('12')
}).catch(async (value) => {
console.log(value)
await new Promise((resolve, reject) => {
reject('13')
console.log('14')
}).catch((value) => {
console.log(value)
})
setTimeout(() => {
console.log('15')
}, 0)
})
console.log('16')
setTimeout(() => {
console.log('17')
}, 0)
}
getUser()
getUser1()
分析
- 宏任务中的同步任务和微任务要在本队列中其他宏任务之前执行
- 微任务和宏任务代码更像是包裹同步任务和其他任务的“容器”
结果:3 12 2 11 14 9 13 16 1 4 6 5 8 10 15 17 7 end
微任务中的微任务
;(async function my() {
await new Promise((resolve, reject) => {
reject('1')
console.log('2')
}).catch(async (value) => {
console.log(value)
await new Promise((reslove, reject) => {
reject('3')
}).catch(async (value) => {
console.log(value)
await new Promise((reslove, reject) => {
reject('4')
}).catch((value) => {
console.log(value)
})
})
})
console.log('5')
setTimeout(() => {
console.log('6')
}, 0)
})()
;(async function my1() {
await new Promise((resolve, reject) => {
reject('7')
console.log('8')
}).catch((value) => {
console.log(value)
})
// 先等待先执行
console.log('9')
setTimeout(() => {
console.log('10')
}, 0)
})()
分析
结果:2 8 1 7 3 9 4 5 10 6
本文含有隐藏内容,请 开通VIP 后查看