异步与事件循环

共 46 题
#

1. async/await 与微任务调度机制

A await 恢复执行通过微任务调度,async 函数返回 Promise,内部抛错转为拒绝 ✓ 正确答案
B await 恢复执行通过宏任务调度
C async 函数内部抛错不会影响返回的 Promise
D await 一个同步值时不会产生任何调度开销
#

2. Promise 状态机与 then/catch/finally 链式行为

A finally 中 return 的值会覆盖原 Promise 结果
B Promise 可以从 fulfilled 回到 pending
C catch 只捕获同步错误
D then 返回新 Promise 并扁平化回调返回的 Promise,finally 不改变向后传递的结果但会执行清理 ✓ 正确答案
#

3. 事件循环的微任务 checkpoint,Promise 回调、MutationObserver 与 DOM 更新批量化的执行时机

A 每个宏任务结束后、渲染前执行微任务 checkpoint 清空微任务队列,DOM 更新在之后渲染阶段批量化合并 ✓ 正确答案
B 微任务只在所有宏任务执行完后执行一次
C MutationObserver 回调走宏任务队列
D 渲染发生在微任务 checkpoint 之前
#

4. setTimeout 嵌套调用的 4ms 钳制与 setTimeout(0) 在任务切片的真实延迟

A 嵌套 setTimeout 超过 5 层后最小延迟钳制为 4ms,后台页面延迟会进一步放大 ✓ 正确答案
B setTimeout(0) 会在当前宏任务结束后立即同步执行
C 定时器嵌套不受任何延迟限制
D 前台页面的 setTimeout 最小延迟是 0
#

5. Web Locks API(navigator.locks)在异步共享资源排他控制的工程应用

A Web Locks 只在单个标签页内有效
B Web Locks 按名称与模式在跨标签页/Worker 间协调,锁持有期等于回调返回的 Promise 生命周期 ✓ 正确答案
C 排他锁允许多个请求者同时进入
D 锁在回调开始执行时就自动释放
#

6. scheduler.postTask/scheduler.wait 优先级任务调度与事件循环的集成边界

A postTask 无法中途中止
B postTask 任务与微任务同一队列
C scheduler.wait 是同步阻塞等待
D scheduler.postTask 按 user-blocking/user-visible/background 优先级在帧调度中安排任务,微任务仍优先于任务执行 ✓ 正确答案
#

7. Long Tasks API(PerformanceObserver longtask 条目)在长任务度量的工程价值

A 长任务指超过 50ms 的网络请求
B 长任务是主线程超过 50ms 的阻塞任务,可用 PerformanceObserver 的 longtask 条目量化并与 INP 关联 ✓ 正确答案
C longtask 条目只包含总时长不包含来源
D 长任务不影响输入响应
#

8. 事件循环中 I/O 任务、渲染任务与微任务的优先级分层(浏览器 vs Node.js)

A 浏览器事件循环有 timers 阶段
B 浏览器与 Node 的事件循环结构完全相同
C Node 中 nextTick 在微任务之后执行
D 浏览器每轮执行宏任务后清空微任务再渲染,Node 按阶段轮询且 process.nextTick 优先于 Promise 微任务 ✓ 正确答案
#

9. Promise.allSettled 的错误隔离与错误聚合(AggregateError)

A AggregateError 是 Promise.all 的拒绝原因
B allSettled 在任一 Promise 拒绝时立即整体拒绝
C allSettled 等待全部落定并返回状态数组实现错误隔离,Promise.any 全部拒绝时以 AggregateError 聚合所有原因 ✓ 正确答案
D allSettled 不保证输入顺序
#

10. 迭代器与生成器协议(Iterator Helpers,map/filter/take/drop)

A 迭代器协议只要求 value 不要求 done
B Iterator Helpers 会立即生成完整中间数组
C 生成器是迭代器工厂,Iterator Helpers 提供惰性链式操作,可在无限序列上安全使用 take 截取 ✓ 正确答案
D for...of 不依赖 Symbol.iterator
#

11. import.meta.resolve/import.meta.url 在 ESM 资源解析的工程取舍

A import.meta.url 返回的是当前页面的 URL
B import.meta.url 提供当前模块 URL 作为相对路径基准,import.meta.resolve 把说明符解析为绝对 URL ✓ 正确答案
C import.meta.resolve 只能解析相对路径
D 相对路径解析应该基于 location.href
#

12. async generator 的提前退出(return/throw)与 finally 清理时机在异步迭代的工程取舍

A generator.throw() 会让生成器永远挂起
B 提前退出不会触发任何清理
C for await...of 提前退出会调用迭代器 return(),async generator 的 finally 先执行完成资源清理 ✓ 正确答案
D async generator 无法表达取消语义
#

13. JavaScript 装饰器(TC39 Stage 3,access/context 二元形态与 decorator metadata)

A 装饰器只能用于类本身
B Stage 3 装饰器签名与 TypeScript legacy 完全相同
C context 中不含 kind 字段
D Stage 3 装饰器接收 (value, context) 二元参数,context 含 kind/name/static 等,元数据经 Symbol.metadata 收集 ✓ 正确答案
#

14. Top-level await 在 ESM 模块的依赖阻塞与加载顺序影响

A Top-level await 只影响自身模块不影响他人
B Top-level await 会阻塞等待该模块求值的导入方与兄弟模块,互不依赖的模块仍并行加载 ✓ 正确答案
C 顶层 await 与循环依赖结合不会产生问题
D 打包器不需要感知顶层 await
#

15. queueMicrotask 与 Promise.resolve().then 的等价性与工程取舍

A 二者执行时机等价,但 queueMicrotask 不创建 Promise,回调抛错形态与 Promise 链不同 ✓ 正确答案
B queueMicrotask 走宏任务队列
C Promise.resolve().then 比 queueMicrotask 更省内存
D queueMicrotask 回调抛错会触发 unhandledrejection
#

16. 微任务饥饿(Microtask Starvation)与渲染阻塞的缓解策略

A 微任务与宏任务一样每轮只执行一个
B 微任务递归会使队列永不清空、渲染与宏任务被饿死,应改用宏任务切分或限制递归深度 ✓ 正确答案
C 微任务饥饿只影响动画不影响输入
D 用 queueMicrotask 递归可以安全执行长任务
#

17. Promise.race 在超时控制与最快响应场景的应用边界

A race 与 any 的语义完全相同
B race 在全部输入拒绝前不会落定
C race 会自动取消其他请求
D race 随最先落定者落定但不会取消落选者,超时控制需配合 AbortController 才能真正中止 ✓ 正确答案
#

18. Promise.all/allSettled/race/any 的并发控制差异

A allSettled 会在首个拒绝时整体拒绝
B race 对空数组立即兑现
C all 快速失败、allSettled 永不整体失败、race 取最先落定、any 取首个兑现且全部失败时聚合 ✓ 正确答案
D any 取最先拒绝者
#

19. 宏任务与微任务的执行顺序(Promise、setTimeout、queueMicrotask、requestAnimationFrame)

A 执行顺序为同步代码→微任务清空→rAF/渲染→宏任务,rAF 回调在渲染前执行 ✓ 正确答案
B setTimeout 回调优先于微任务执行
C requestAnimationFrame 在宏任务之后执行
D 微任务每轮只执行第一个
#

20. ESM 静态依赖图与 Tree Shaking 的工程影响

A ESM 静态依赖图使未引用导出可被裁剪,sideEffects:false 标记允许整模块级死代码消除 ✓ 正确答案
B CommonJS 也能被可靠地 Tree Shaking
C 模块顶层副作用不影响 Tree Shaking
D Tree Shaking 是运行时行为
#

21. AbortSignal 的复合取消(AbortSignal.any)与超时清理的协作

A AbortSignal.any 组合多个信号任一中止即中止,可与 AbortSignal.timeout 协作实现手动取消加自动超时 ✓ 正确答案
B AbortSignal.any 要求所有信号都中止
C AbortSignal.timeout 只能用于 fetch
D abort 事件只能触发一次
#

22. AbortController 与 AbortSignal.timeout、AbortSignal.any 的取消传播

A controller.abort() 通过 signal 的 abort 事件传播取消,signal 可传给多个异步操作实现全链路取消 ✓ 正确答案
B 每个异步操作必须使用独立 controller
C 已中止的 signal 传给 fetch 不会报错
D abort 事件携带取消原因参数
#

23. 动态 import()、Import Attributes(with { type: ... })的代码分割

A 动态 import() 让打包器拆分独立 chunk 实现按需加载,Import Attributes 为模块显式声明类型 ✓ 正确答案
B 动态 import 与静态 import 打包结果相同
C Import Attributes 只用于 CSS
D 动态 import() 不支持错误处理
#

24. unhandledrejection 事件的触发时机与职责边界

A unhandledrejection 在微任务轮询结束时仍未处理拒绝时触发,是全局兜底而非业务错误处理 ✓ 正确答案
B 拒绝瞬间立即触发 unhandledrejection
C 该事件无法被 preventDefault
D 业务层无需处理错误,靠事件即可
#

25. Promise.withResolvers、Promise.try 的语义简化

A withResolvers 一次返回 promise/resolve/reject,Promise.try 统一同步抛错与异步拒绝的错误通道 ✓ 正确答案
B Promise.try 只能处理纯异步函数
C withResolvers 无法在 executor 外落定 Promise
D Promise.try 会把同步返回值变成拒绝
#

26. BroadcastChannel 与 MessageChannel 在跨上下文异步消息传递的差异

A BroadcastChannel 只能一对一
B BroadcastChannel 是同源一对多广播,MessageChannel 是一对一定向管道且端口可转移 ✓ 正确答案
C MessageChannel 可以自动跨域通信
D 两者都不能传输 ArrayBuffer
#

27. 异步瀑布流(waterfall)vs 并发,串行 await 与 Promise.all 在依赖请求与并行请求的取舍

A 串行 await 的总耗时等于最慢请求
B Promise.all 会按顺序逐个执行
C 存在数据依赖时必须串行 await,独立请求用 Promise.all 并行但需控制并发上限 ✓ 正确答案
D 并发请求数永远越多越好
#

28. import.meta.resolve() 在模块路径解析与 SSR 中的应用

A ESM 中可以直接使用 __dirname
B import.meta.resolve 只能解析内置模块
C import.meta.resolve 把说明符解析为绝对 URL,可用于运行时定位模块路径与 SSR 产物路径治理 ✓ 正确答案
D resolve 的返回结果是相对路径
#

29. scheduler.yield() 协作式让步在长任务切片的浏览器支持与边界

A scheduler.yield 让出主线程至调度器择机恢复,用于长任务切片,目前需特性检测并降级 ✓ 正确答案
B scheduler.yield 会同步阻塞等待
C scheduler.yield 与 setTimeout(0) 完全相同
D scheduler.yield 在所有浏览器可用
#

30. JavaScript 单线程事件循环与微任务队列(microtask)

A 微任务在渲染之后执行
B 微任务与宏任务在同一队列排队
C 异步回调由 JS 主线程自己完成
D 单线程通过事件循环调度宏任务与微任务双队列,每轮清空微任务后再渲染与执行宏任务 ✓ 正确答案
#

31. async/await 在错误传播与栈追踪相较于 Promise 链的工程取舍

A async/await 以 try/catch 统一捕获同步与异步错误,现代引擎提供异步栈追踪增强可读性 ✓ 正确答案
B await 链的栈追踪总是完整的
C Promise 链比 await 更容易捕获错误
D try/catch 无法捕获 await 的拒绝
#

32. ES Module 与 CommonJS 在循环依赖、默认导出与 tree-shaking 的差异

A ESM 在 require 时同步执行
B CJS 与 ESM 的导出语义完全相同
C CJS 可以被可靠地 Tree Shaking
D ESM 导出是实时绑定且静态可分析,循环依赖通常可工作;CJS 复制导出值、依赖运行时 ✓ 正确答案
#

33. 动态 import() 在代码分割、路由懒加载与 SSR 的工程应用

A 路由懒加载不需要错误兜底
B 动态 import 无法分割代码
C 动态 import() 产生独立 chunk 支撑路由懒加载,SSR 需保证双端路径与 chunk 清单一致 ✓ 正确答案
D SSR 与服务端动态 import 无关
#

34. 宏任务(setTimeout、setInterval)

A setInterval 保证回调精确按周期完成
B setInterval 的周期是发起间隔,回调耗时过长会漂移堆叠,需递归 setTimeout 或时间戳校正 ✓ 正确答案
C setTimeout 回调执行期间不受钳制
D 定时器无需清理
#

35. AbortController 与 AbortSignal 在 fetch、流与定时器的协作取消

A signal 只能取消 fetch
B 同一 signal 可传给 fetch、流与定时器,abort 时各 API 自行取消,需手动清理 abort 监听 ✓ 正确答案
C 流无法被 signal 取消
D abort 后无需区分错误类型
#

36. 事件循环中的 requestAnimationFrame 与浏览器渲染时机的协作机制

A 后台页面 rAF 照常高频执行
B rAF 在宏任务之后任意时刻执行
C rAF 每帧可以执行任意多次
D rAF 回调在渲染前每帧执行一次、与刷新率对齐,后台页面自动暂停 ✓ 正确答案
#

37. 事件循环的 MessageChannel 与 postMessage 在微任务调度的差异

A MessageChannel 消息是微任务
B MessageChannel 消息是宏任务但比 setTimeout 更早、不受 4ms 钳制,曾被用于模拟微任务 ✓ 正确答案
C postMessage 只能同线程使用
D 现代环境应优先用 MessageChannel 模拟微任务
#

38. Generator 函数与 async generator 在异步迭代(for-await-of)

A async generator 内部不能使用 await
B async generator 由 for...of 消费
C async generator 的 next 返回 Promise,由 for await...of 消费,内部可用 await 表达异步流 ✓ 正确答案
D for await...of 不支持提前退出
#

39. Import Maps(<script type="importmap">)的裸模块说明符别名、scopes 作用域映射与浏览器原生解析机制

A scopes 与 imports 优先级相同且互不影响
B importmap 可以随时动态修改
C Import Maps 用 imports 映射裸说明符、scopes 按 URL 前缀细分,解析遵循最长匹配且须在模块加载前声明 ✓ 正确答案
D 未匹配的说明符会静默解析为空
#

40. Import Maps 与构建工具(Vite/Webpack)产物中模块解析的关系及 no-bundler CDN 直载模式的工程边界

A 构建工具在构建期重写裸说明符,Import Maps 在运行期解析,CDN 直载需显式锁定版本且缺少构建期优化 ✓ 正确答案
B Import Maps 与构建工具解析时机相同
C CDN 直载无需考虑依赖版本
D 所有包都可直接 ESM 直载
#

41. Dynamic Import 的预加载(<link rel="modulepreload">)在性能优化

A modulepreload 只能用于入口模块
B modulepreload 会立即执行模块副作用
C modulepreload 与 prefetch 完全相同
D modulepreload 预取并解析缓存模块供动态 import 命中,不会提前执行模块副作用 ✓ 正确答案
#

42. ES Module 的副作用(side-effect-free)

A sideEffects:false 表示模块永不执行
B sideEffects:false 声明模块无副作用以允许整模块裁剪,副作用模块(polyfill/CSS)需显式保留 ✓ 正确答案
C CSS 永远可以安全裁剪
D 副作用声明不影响打包结果
#

43. Promise.withResolvers() 在外部 resolve 异步操作的现代应用

A executor 闭包模式无法实现外部落定
B withResolvers 只能落定一次且不能解构
C withResolvers 把 Promise 创建与落定解耦,适合事件驱动与回调桥接场景 ✓ 正确答案
D withResolvers 会改变微任务调度
#

44. Worker 模块(new Worker(url, {type: 'module'}))相较传统脚本的工程取舍

A 传统 Worker 支持 import 语法
B 模块 Worker 支持 importScripts
C 模块 Worker 支持 import/顶层 await 与模块化组织,但需 CORS 且旧环境要降级 ✓ 正确答案
D 模块 Worker 与主线程共享 DOM
#

45. 事件循环在浏览器与 Node.js 的差异(nextTick、process.nextTick 优先级)

A process.nextTick 与 Promise 微任务同一队列
B Node 按阶段轮询且 process.nextTick 优先于微任务,浏览器按宏任务/微任务/渲染帧模型循环 ✓ 正确答案
C 浏览器也有 setImmediate
D Node 事件循环包含渲染阶段
#

46. Import Maps 与 Module Federation 的演进关系,运行时模块解析、共享依赖治理与微前端远程加载的取舍

A Import Maps 会自动协商依赖版本
B Import Maps 与 Module Federation 机制完全相同
C Module Federation 不需要构建工具
D Module Federation 在构建期生成运行时映射并协商共享依赖版本,Import Maps 是浏览器原生 URL 映射,二者可互补 ✓ 正确答案