120 lines
2.5 KiB
Markdown
120 lines
2.5 KiB
Markdown
# 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)
|
||
``` |