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

2.5 KiB
Raw Permalink Blame History

5-事件循环机制

宏任务, 微任务

// 打印顺序
setTimeout(()=>(
  console.log(1)
),0)

Promise.resolve(1).then(()=>{
  console.log(2)
})

console.log(3)

js 是单线程的, 基于事件循环机制 (even loop) 来处理异步任务, 不断检查调用栈和任务队列 当调用栈中的代码执行完毕后, 队列中的代码才会按照顺序依次进入到栈中执行 - 调用栈: 放要执行的代码 - 栈: 是一种数据结构, 后进先出 (类似叠盘子) - 全局作用域的代码, 是放在栈里的 - 任务队列: 等待执行的代码 - 队列: 是一种数据结构, 先进先出 (类似排队) - 任务队列有两种: - 宏任务队列: 大部分代码都去宏任务队列排队 - 微任务队列: Promise 的回调函数 (then, catch, finally)

===执行顺序: 调用栈 ==> 微任务队列 ==> 宏任务队列===

  • 调用栈包括:
全局代码例如变量声明函数定义同步函数调用等
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. 全局执行上下文从调用栈弹出。
*/
  • 微任务包含:
Promise.then
Object.observe
MutationObserver // 突变观察者
process.nextTick(Node.js 环境)

Promise 在执行then 就相当于给 Promise 设置了回调函数, 当 Promise 的状态从 pending 变为 fulfilled 时then 的回调函数会被放入到微任务队列中

  • 宏任务包含:
script(整个标签或整个外部文件)
setTimeout
setInterval
I/O
UI交互事件
postMessage
MessageChannel
setImmediate(Node.js 环境)

定时器: 间隔一段时间后, 将函数放到宏任务队列

queueMicrotask 微任务队列

// queueMicrotask 把函数添加到微任务队列
queueMicrotask(()=>{
  console.log(5)
})
Promise.resolve().then(()=>{
  Promise.resolve().then(()=>{
    console.log('a')
  })
})

queueMicrotask(()=>{
  console.log('b')
})
// b a
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)