MST

星途 面试题库

面试题:JavaScript 中 Promise 在网络请求与微任务队列交互的深度剖析

已知网络请求是异步操作,Promise 也涉及异步处理以及微任务队列。当在一个网络请求的 Promise 回调中又创建新的 Promise 并添加微任务时,详细描述整个事件循环过程以及微任务队列的变化情况。同时,说明这种情况下可能会出现的性能问题及优化方法。
28.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

事件循环过程及微任务队列变化情况

  1. 网络请求阶段:网络请求发起,这是一个异步操作,它不会阻塞主线程,JavaScript 引擎继续执行后续代码。
  2. Promise 回调执行:当网络请求完成,其对应的 Promise 的 then 回调会被放入微任务队列。此时,如果当前执行栈为空,事件循环会从微任务队列中取出这个回调并放入执行栈执行。
  3. 新 Promise 创建及微任务添加:在 then 回调中创建新的 Promise 并添加微任务(例如使用 Promise.resolve().then()),新的微任务会被添加到微任务队列的末尾。
  4. 事件循环继续:当前执行栈中的 then 回调执行完毕后,事件循环再次检查微任务队列,若有任务则依次取出放入执行栈执行。新添加的微任务会按顺序执行。只有当微任务队列清空后,事件循环才会去检查宏任务队列,取出下一个宏任务放入执行栈执行。

可能出现的性能问题

  1. 微任务过多阻塞主线程:如果在 Promise 回调中频繁创建新的 Promise 并添加微任务,微任务队列可能会积累大量任务,导致主线程长时间被占用,影响页面的渲染和用户交互响应。
  2. 内存泄漏风险:过多未处理的 Promise 回调以及微任务可能导致内存占用不断增加,引发内存泄漏问题。

优化方法

  1. 减少微任务创建频率:避免在 Promise 回调中不必要地创建新的 Promise 和添加微任务,尽量合并操作,减少微任务数量。
  2. 使用 requestIdleCallback:对于一些非紧急的任务,可以使用 requestIdleCallback 把任务放到浏览器空闲时段执行,避免阻塞主线程。
  3. 合理处理 Promise:确保 Promise 链的长度合理,及时释放不再使用的 Promise 引用,防止内存泄漏。同时,避免在 Promise 中进行过于复杂和耗时的同步操作。