Event Loop
事件循环(Event Loop)指的是计算机系统的一种运行机制,JavaScript采用这种机制来解决单线程运行带来的一些问题。
JavaScript为什么设计成单线程?
事件循环机制
主线程从任务队列中读取任务,执行任务,整个过程是循环往复的,整个运行机制又被称为Event Loop
// 两分钟视频理解Event Loop
www.bilibili.com/video/BV1kf…
宏任务和微任务
事件循环中的执行步骤
思考题
进程和线程的关系
进程可以包含多个线程。
比如打开一个页面,这个页面占用了计算机的一个进程,页面加载时,浏览器会分配多个线程去计算DOM树、执行JS脚本、加载资源文件等。
宏任务和页面渲染的顺序关系
浏览器为了能够使得JS内部宏任务与DOM任务能够有序的执行,会在一个宏任务执行结束后,在下一个宏任务执行开始前,对页面进行重新渲染。流程如下:
(macro)task->渲染->(macro)task->...
为什么要引入微任务,只有宏任务可以吗?
微任务的引入是为了解决异步回调的问题。
假设只有宏任务,那么每一个宏任务执行完后回调函数也放入宏任务队列,这样会造成队列多长,回调的时间变长,这样会造成页面的卡顿,所以引入了微任务。
await后面的代码会进入到promise队列中的微任务
async/await 只是操作 promise 的语法糖,最后的本质还是promise。
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
// 上面的代码等价于 ==>
async function async1() {
console.log('async1 start');
Promise.resolve(async2()).then(() => {
console.log('async1 end')
})
}
例题
例题1
console.log("start");
setTimeout(() => {
console.log("children2")
Promise.resolve().then(() =>{
console.log("children3")
})
}, 0)
new Promise(function(resolve, reject){
console.log("children4")
setTimeout(function(){
console.log("children5")
resolve("children6")
}, 0)
}).then(res =>{ // flag
console.log("children7")
setTimeout(() =>{
console.log(res)
}, 0)
})
// start children4 children2 children3 children5 children7 children6
上面的.then() (注释的flag处) 不是第一轮宏任务循环的微任务。因为resolve都没有执行,promise的状态都还没有从pending改变,就不是第一轮的微任务。
例题2
async function async1() {
console.log('async1 start')
await async2()
console.log('async1 end')
}
async function async2() {
console.log('async2')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
async1()
new Promise((resolve) => {
console.log('promise1')
resolve()
}).then(function () {
console.log('promise2')
})
console.log('script end')
//输出
//script start
//async1 start
//async2
//promise1
//script end
//async1 end
//promise2
//setTimeout
例题3
async function async1() {
console.log('async1 start');
await async2();
console.log('async1 end');
}
async function async2() {
new Promise(function (resolve) {
console.log('promise1');
resolve();
}).then(function () {
console.log('promise2');
});
}
console.log('script start');
setTimeout(function () {
console.log('setTimeout');
}, 0)
async1();
new Promise(function (resolve) {
console.log('promise3');
resolve();
}).then(function () {
console.log('promise4');
});
console.log('script end');
//script start,
// async1 start,
// promise1,
// promise3,
// script end,
// promise2,
// async1 end,
// promise4,
// setTimeout
例题4
async function async1() {
console.log('async1 start');
await async2();
setTimeout(function() {
console.log('setTimeout1')
},0)
}
async function async2() {
setTimeout(function() {
console.log('setTimeout2')
},0)
}
console.log('script start');
setTimeout(function() {
console.log('setTimeout3');
}, 0)
async1();
new Promise(function(resolve) {
console.log('promise1');
resolve();
}).then(function() {
console.log('promise2');
});
console.log('script end');
// script start, async1 start, promise1, script end, promise2, setTimeout3, setTimeout2, setTimeout1