管理

(转载)20个JavaScript重点知识点(15)Event Loop机制

Posted on 2025-07-10 12:01  lzhdim  阅读(10163)  评论(0)    收藏  举报

一、为什么需要 Event Loop?

JavaScript 是 单线程语言,意味着它一次只能执行一个任务。但浏览器中需要处理大量异步操作(如网络请求、定时器、用户事件),如果让主线程等待这些操作完成,会导致页面“卡死”。Event Loop(事件循环) 的机制让 JS 在单线程下也能实现非阻塞异步执行。通过 Event Loop 机制实现了:

  • 1.非阻塞 I/O 操作

  • 2.异步任务处理

  • 3.高并发处理能力

二、核心架构图解

┌───────────────────────┐│        Call Stack     │ ← 同步代码执行└──────────┬────────────┘           │           │┌──────────▼────────────┐│   Web APIs/DOM APIs   │ ← 定时器/事件监听/网络请求└──────────┬────────────┘           │           │┌──────────▼────────────┐│  Task Queue (Macro)   │ ← setTimeout/setInterval/UI事件├───────────────────────┤│  Microtask Queue      │ ← Promise/MutationObserver└──────────┬────────────┘           │┌──────────▼────────────┐│     Event Loop        │ ← 持续检查队列的调度机制└───────────────────────┘

三、执行顺序规则

 

  1. 1.执行同步代码直至调用栈清空

  2. 2.执行所有微任务(Microtasks)

  3. 3.执行一个宏任务(Macrotask)

  4. 4.重复循环

四、代码演示

console.log('1. Script Start');
setTimeout(() => {  console.log('6. setTimeout');}, 0);
new Promise((resolve) => {  console.log('2. Promise Constructor');  resolve();}).then(() => {  console.log('4. Promise Then 1');}).then(() => {  console.log('5. Promise Then 2');});
console.log('3. Script End');
// 输出顺序:// 1. Script Start// 2. Promise Constructor// 3. Script End// 4. Promise Then 1// 5. Promise Then 2// 6. setTimeout
  1. 五、任务类型分类

  2. 任务类型示例优先级
    微任务(Micro) Promise.then / queueMicrotask
    宏任务(Macro) setTimeout / setInterval
    渲染任务 requestAnimationFrame 特殊

     

 

六、实战应用

1. 性能优化

// 错误示例:阻塞主线程function longTask() {  for(let i=0; i<1e7; i++){     // 长时间同步计算  }}
// 正确做法:分解任务function chunkedTask() {  let i = 0;  function processChunk() {    while(i < 1e7 && performance.now() - start < 50) {      i++    }    if(i < 1e7) {      setTimeout(processChunk);    }  }  const start = performance.now();  processChunk();}

2. 优先级控制

// 微任务优先处理button.addEventListener('click', () => {  Promise.resolve().then(() => {    console.log('Microtask handling click');  });  setTimeout(() => {    console.log('Macrotask handling click');  });});

3. 混合任务处理

console.log('Start');
setTimeout(() => console.log('Timeout'), 0);
Promise.resolve()  .then(() => {    console.log('Promise 1');    queueMicrotask(() => console.log('Microtask in Promise'));  })  .then(() => console.log('Promise 2'));
console.log('End');
/* 输出顺序:StartEndPromise 1Promise 2Microtask in PromiseTimeout*/

七、常见问题

1. 函数节流优化

function throttle(fn, delay) {  let lastCall = 0;  return (...args) => {    const now = Date.now();    if(now - lastCall >= delay) {      fn(...args);      lastCall = now;    } else {      requestAnimationFrame(() => throttle(fn, delay)(...args));    }  };}

2. 竞态条件处理

let controller = new AbortController();
async function fetchData() {  try {    const response = await fetch(url, {      signal: controller.signal    });    // 处理响应  } catch (e) {    if (e.name === 'AbortError') {      console.log('请求已取消');    }  }}
// 取消前一个请求function refreshData() {  controller.abort();  controller = new AbortController();  fetchData();}

Web Workers 集成

// 主线程const worker = new Worker('worker.js');
worker.onmessage = (e) => {  console.log('Received:', e.data);};
worker.postMessage('Start');
// worker.jsself.onmessage = (e) => {  const result = heavyCalculation(e.data);  self.postMessage(result);};

理解 Event Loop 的运行机制所带来的优势:

  • 1.编写更高效的异步代码

  • 2.避免常见性能陷阱

  • 3.实现流畅的交互体验

  • 4.更好地处理复杂任务调度

Copyright © 2000-2022 Lzhdim Technology Software All Rights Reserved