事件循环
JavaScript是单线程
学习及参考网址
阮一峰 JavaScript 运行机制详解:再谈Event Loop
JavaScript语言的一大特点就是单线程,同一时间只能做一件事情。
任务队列
单线程就意味着,代码是从上向下执行的,所有任务需要进行排队,前一个任务结束的时候,下一个任务才会进行执行。
因此这些任务被分为了两种:
- 同步任务
- 异步任务
同步指:在主线程上进行排队的任务,只有前一个任务执行完毕,才会执行后一个任务
异步指:不进入主线程,而进入任务队列的任务,只有“任务队列”通知主线程,某个异步任务可以执行了,该任务才会进入主线程执行。
一般情况下,任务执行可以分为三个队列
主线程 | 微任务 | 宏任务 |
---|---|---|
console.log() | Promise.then | setTimeout |
接口调用 | ||
一般情况下执行顺序为:主线程 > 微任务 > 宏任务
可以用几个题来将事件循环弄明白,上题!
setTimeout(function () {
console.log('setTimeout1')
new Promise(function (resolve) {
resolve()
}).then(function () {
new Promise(function (resolve) {
resolve()
}).then(function () {
console.log('then4')
})
console.log('then2')
})
})
new Promise(function (resolve) {
console.log('promise1')
resolve()
}).then(function () {
console.log('then1')
})
setTimeout(function () {
console.log('setTimeout2')
})
console.log(2)
queueMicrotask(() => {
console.log('queueMicrotask1')
})
new Promise(function (resolve) {
resolve()
}).then(function () {
console.log('then3')
})
// promise1
// 2
// then1
// queueMicrotask1
// then3
// setTimeout1
// then2
// then4
// setTimeout2
代码执行时,由上向下依次执行,setTimeout进入宏任务队列,接着向下执行到Promise,之前我一度以为只要进入到Promise的调用时就进入了异步队列中,其实这个想法是错误的,Promise只有进入.then的时候才是进入了微任务队列,因此promise1直接输出,遇到Promise.then,进入微任务队列中进行等待,后面setTimeout再次进入宏任务队列,输出2,queueMicrotask也是微任务队列,因此进入微任务队列中,再次遇到Promise.then,进入微任务队列。因此执行顺序为目前表格所示。
主线程 | 微任务 | 宏任务 |
---|---|---|
promise1 | then1 | setTimeout1及之后代码 |
2 | queueMicrotask1 | setTimeout2 |
then3 |
事件循环是JavaScript中必须学习的一部分,通过代码题将自己的基础再进行巩固。