1 - 同步和异步
-
js是一门单线程语言,在同一时间只能做一件事情
-
同步任务会在主线程上执行,异步任务会进入任务队列,等待主线程任务执行完成后再将任务队列中的任务放入主线程执行
2 - 宏任务和微任务
异步任务又分为宏任务和微任务,宏任务会进入任务队列,而微任务不会进入任务队列,但微任务会等待同步任务执行完毕后执行
- 宏任务:script(整体代码)、 setTimeout、 setInterval、ajax、事件绑定等
- 微任务:Promise.then/.catch/.finally(promise本身是同步,只有.then或catch或finally才是异步)、process.nextTick(Node.js 环境)
一段script标签中宏任务和微任务的执行顺序为:
同步任务 -> 异步微任务 -> 异步宏任务
setTimeout(() => { console.info(1) }) // 异步宏任务 - 在异步微任务之后执行
Promise.resolve().then(() => { console.info(3) }) // 异步微任务 - 在同步任务后执行
console.info(2) // 同步任务 - 优先执行
// 结果 2 - 3 - 1
console.info(1)
setTimeout(() => {
Promise.resolve().then(() => {
console.info(2)
})
console.info(3)
})
console.info(4)
new Promise((resolve) => {
console.info(5)
resolve()
}).then(() => {
console.info(6)
})
setTimeout(() => {
console.info(7)
setTimeout(() => {
console.info(8)
})
})
console.info(9)
// 结果 1 - 4 - 5 - 9 - 6 - 3 - 2 - 7 - 8
上面这段代码中:
- 首先执行在主线程上的同步任务,即 1 4 5 9 (打印了5是因为Promise本身为同步,.then才是异步(微任务))
- 再去执行异步微任务 6
- 再执行第一任务队列异步宏任务(第一个setTimeout)3 2
- 再执行第二任务队列异步宏任务(第二个setTimeout)7
- 再执行第三任务队列异步宏任务(第三个setTimeout)8