devStandard/docs/learning/3-js/5-事件循环机制.md
2025-03-29 14:35:49 +08:00

120 lines
2.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 5-事件循环机制
## 宏任务, 微任务
```js
// 打印顺序
setTimeout(()=>(
console.log(1)
),0)
Promise.resolve(1).then(()=>{
console.log(2)
})
console.log(3)
```
> js 是单线程的, 基于事件循环机制 (even loop) 来处理异步任务, 不断检查调用栈和任务队列
> 当调用栈中的代码执行完毕后, 队列中的代码才会按照顺序依次进入到栈中执行
> - 调用栈: 放要执行的代码
> - 栈: 是一种数据结构, 后进先出 (类似叠盘子)
> - 全局作用域的代码, 是放在栈里的
> - 任务队列: 等待执行的代码
> - 队列: 是一种数据结构, 先进先出 (类似排队)
> - 任务队列有两种:
> - 宏任务队列: 大部分代码都去宏任务队列排队
> - 微任务队列: Promise 的回调函数 (then, catch, finally)
===执行顺序: 调用栈 \==> 微任务队列 \==> 宏任务队列===
* 调用栈包括:
```js
全局代码例如变量声明函数定义同步函数调用等
```
```js
console.log("Start");
function foo() {
console.log("foo");
}
foo();
console.log("End");
/**
1. 全局执行上下文被推入调用栈。
2. `console.log("Start")` 执行。
3. `foo()` 被推入调用栈。
4. `console.log("foo")` 执行,`foo()` 从调用栈弹出。
5. `console.log("End")` 执行。
6. 全局执行上下文从调用栈弹出。
*/
```
* 微任务包含:
```js
Promise.then
Object.observe
MutationObserver // 突变观察者
process.nextTick(Node.js 环境)
```
Promise 在执行then 就相当于给 Promise 设置了回调函数, 当 Promise 的状态从 pending 变为 fulfilled 时then 的回调函数会被放入到微任务队列中
* 宏任务包含:
```js
script(整个标签或整个外部文件)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)
```
定时器: 间隔一段时间后, 将函数放到宏任务队列
### queueMicrotask 微任务队列
```js
// queueMicrotask 把函数添加到微任务队列
queueMicrotask(()=>{
console.log(5)
})
```
```js
Promise.resolve().then(()=>{
Promise.resolve().then(()=>{
console.log('a')
})
})
queueMicrotask(()=>{
console.log('b')
})
// b a
```
```js
console.log(1)
setTimeout(() => console.log(2))
Promise.resolve().then(() => console.log(3))
Promise.resolve().then(() => setTimeout(() => console.log(4)))
Promise.resolve(). then(() => console.log(5))
setTimeout(() => console.log(6))
console.log(7)
```