eventloop事件循环的笔记
1.事件循环的基本概念
eventLoop指的是事件循环 它决定了JS中的异步代码和同步代码的执行方式
1 执行栈 执行代码的内存
2 事件队列 决定事件谁先谁后的执行顺序的队列 也叫做任务队列
2.1 宏任务队列 定时器、回调函数、事件函数
2.2 微任务队列 then 和 catch
执行代码的顺序
第一步
浏览器加载JS的时候 先把所有的代码放入执行栈
一条一条的执行
执行过程中 不可避免的会有异步行为 比如定时器 比如事件 比如 Promise等
如果遇见了定时器 setInterval() setTimeout() 就开启定时器
如果遇见了绑定事件 dom.onclick = function(){} 就绑定事件
如果遇见了 .then() .catch() 会把这两个参数函数 绑定给Promise实例
重复以上过程 直到清空执行栈
2.只有宏任务的时候
for (var i = 0; i < 10; i++) {
console.log(i);
}
setTimeout(function() {
console.log("i")
}, 10000);
document.onclick = function() {
console.log("哈哈哈")
}
setTimeout(function() {
console.log("i1")
}, 5000);
for (var i = 10; i < 20; i++) {
console.log(i)
}
/*
首先把所有代码推入执行栈
按照顺序一条一条的执行
循环先执行 所以顺序输出 0 ~ 9
开启定时器
绑定事件
开启另一个定时器
循环输出 10 ~ 19
至此 执行栈清空
任务队列也是空的
此后的执行就没有顺序可言 谁先到任务队列中排队 谁就先执行
*/
//答案:0-19 i1 i 如果有点击的话就哈哈哈
3.有宏任务又有微任务的时候
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
var a = 10;
setTimeout(function() {
console.log(a)
}, 1000)
console.log("1");
let p = new Promise(function(resolve, reject) {
console.log("4");
resolve();
});
// console.log(p)
p.then(function() {
console.log("2")
})
console.log("3")
// 执行栈清空之后,会去微任务队列中拿一个函数出来 执行掉 再拿一个任务出来 执行掉 直到清空微任务队列
// 微任务队列清空后 再去宏任务队列中拿一个函数出来 执行掉
// 如果宏任务导致出现了新的微任务 会先把微任务清空 再去执行下一个宏任务
</script>
</body>
</html>
答案:1 4 3 2 10
4.测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script>
// 1 输出2
console.log(2);
// 2 开启定时器 10毫秒之后 推入宏任务队列
setTimeout(function() {
// 15 输出1
console.log(1)
}, 0)
// 3 初始化Promise实例
new Promise(function(resolve) {
// 4 输出3
console.log(3)
// 5 状态变为成功
resolve();
// 6 绑定then 因为状态已经发生变化 所以立即将这个函数放入微任务队列
}).then(function() {
// 12 输出4
console.log(4)
// 13 开启定时器 0毫秒之后 推入宏任务
setTimeout(function() {
// 16 输出6
console.log(6)
}, 0)
})
// 7 输出5
console.log(5);
// 8 初始化一个Promise实例
new Promise(function(resolve, reject) {
// 9 状态变为失败
reject()
})
.then(function() {
})
// 10 把函数交给Promise实例 因为状态已经发生变化 所以立即放入微任务队列
.catch(function() {
// 14 开启定时器 将函数0毫秒之后推入宏任务队列
setTimeout(function() {
// 17 输出7
console.log(7)
}, 0)
})
// 11 至此 执行栈清空
// 宏任务队列 第1个函数 第2个函数 第3个函数
// 微任务队列
</script>
</body>
</html>