Appearance
JavaScript 异步解决方案全面解析
回调函数(Callback)
回调函数是 JavaScript 中最原始、最基础的异步处理方式。将一个函数作为参数传递给另一个函数,在异步操作完成后调用该函数。
javascript
function fetchData(url, callback) {
ss
const xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.onload = function () {
if (xhr.status === 200) {
callback(null, xhr.responseText)
} else {
callback(new Error('Request failed'))
}
}
xhr.send()
}
fetchData('/api/data', function (err, data) {
if (err) {
console.error(err)
return
}
console.log(data)
})优点:
- 简单直观,容易理解
- 兼容性极好,所有浏览器和 Node.js 环境都支持
- 无需额外依赖,是 JavaScript 语言原生支持的方式
- 适合简单的、单次的异步操作
缺点:
- 回调地狱(Callback Hell):多层嵌套导致代码可读性极差,形成"金字塔"结构
- 错误处理困难:无法使用 try/catch,每个回调都需要单独处理错误
- 控制流混乱:难以实现并行、串行、竞速等复杂控制流
- 耦合度高:回调函数与调用者紧密耦合,难以复用
- 缺乏返回值:回调函数的返回值无法被外部获取
适用场景:
- 简单的、单次异步操作(如事件监听、setTimeout)
- Node.js 早期 API(fs.readFile 等)
- 需要极致兼容性的旧项目
- 作为其他异步方案的基础构建块
事件监听(Event Listeners)
利用 DOM 的事件机制或 Node.js 的 EventEmitter 来处理异步操作的结果。
javascript
// DOM 事件监听
const button = document.getElementById('myButton')
button.addEventListener('click', function (event) {
console.log('Button clicked!', event)
})
// Node.js EventEmitter
const EventEmitter = require('events')
const emitter = new EventEmitter()
emitter.on('data', function (data) {
console.log('Received data:', data)
})
emitter.on('error', function (err) {
console.error('Error:', err)
})
// 触发事件
emitter.emit('data', { name: 'test' })优点:
- 解耦性好,发布者和订阅者互不依赖
- 支持多个监听器,一个事件可以被多个函数响应
- 可以随时添加或移除监听器,灵活性高
- DOM 事件模型是前端开发的基础,使用自然
缺点:
- 事件流程难以追踪,调试困难
- 多个监听器的执行顺序不可控
- 可能产生内存泄漏(忘记移除监听器)
- 缺乏结构化的错误处理机制
- 不适合需要返回值的场景
- 一次性事件需要手动移除监听器(或使用 once)
适用场景:
- DOM 交互(点击、输入、滚动等用户事件)
- Node.js 中的 Stream 处理
- 组件间通信(如 Vue 的 EventBus)
- 需要一对多通知的场景
发布订阅模式(Pub/Sub Pattern)
发布订阅模式是事件监听的进阶版本,通过一个中心化的消息代理(Event Bus / Message Broker)来管理事件的发布和订阅。
javascript
class EventBus {
constructor() {
this.events = {}
}
on(event, callback) {
if (!this.events[event]) {
this.events[event] = []
}
this.events[event].push(callback)
return () => this.off(event, callback)
}
off(event, callback) {
if (!this.events[event]) return
this.events[event] = this.events[event].filter(cb => cb !== callback)
}
emit(event, ...args) {
if (!this.events[event]) return
this.events[event].forEach(callback => callback(...args))
}
once(event, callback) {
const wrapper = (...args) => {
callback(...args)
this.off(event, wrapper)
}
this.on(event, wrapper)
}
}
const bus = new EventBus()
const unsubscribe = bus.on('user:login', user => {
console.log(`Welcome, ${user.name}!`)
})
bus.emit('user:login', { name: 'Alice' })
unsubscribe() // 取消订阅优点:
- 完全解耦,发布者和订阅者互不知道对方的存在
- 支持多对多通信,一个事件多个订阅者,一个订阅者多个事件
- 高度灵活,可以动态添加/移除订阅
- 支持跨模块、跨组件通信
- 易于扩展,可以添加中间件、过滤器等
缺点:
- 调试困难,事件流向不透明
- 可能导致内存泄漏(订阅者未正确取消订阅)
- 缺乏类型安全,事件名称和参数容易出错
- 全局事件总线可能导致命名冲突
- 过度使用会导致代码难以维护
适用场景:
- 跨组件通信(如兄弟组件通信)
- 插件系统
- 微前端架构中的模块通信
- 需要高度解耦的大型应用
Promise
Promise 是 ES6 引入的异步编程解决方案,表示一个异步操作的最终完成(或失败)及其结果值。
javascript
function fetchData(url) {
return new Promise((resolve, reject) => {
const xhr = new XMLHttpRequest()
xhr.open('GET', url)
xhr.onload = function () {
if (xhr.status === 200) {
resolve(JSON.parse(xhr.responseText))
} else {
reject(new Error(`HTTP Error: ${xhr.status}`))
}
}
xhr.onerror = function () {
reject(new Error('Network Error'))
}
xhr.send()
})
}
// 链式调用
fetchData('/api/user')
.then(user => fetchData(`/api/posts?userId=${user.id}`))
.then(posts => console.log(posts))
.catch(err => console.error(err))
.finally(() => console.log('Request complete'))
// Promise 并行
Promise.all([fetchData('/api/user'), fetchData('/api/posts')])
.then(([user, posts]) => console.log(user, posts))
.catch(err => console.error(err))
// Promise 竞速
Promise.race([
fetchData('/api/fast'),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), 5000)
)
])
.then(data => console.log(data))
.catch(err => console.error(err))优点:
- 解决了回调地狱问题,通过链式调用使代码扁平化
- 统一的错误处理,通过
.catch()集中捕获异常 - 支持链式调用,代码可读性好
- 提供丰富的静态方法:
Promise.all、Promise.race、Promise.allSettled、Promise.any - 状态不可逆(pending → fulfilled / rejected),行为可预测
- 支持异步操作的组合和编排
缺点:
- 一旦创建无法取消(Promise 缺乏内置的取消机制)
- 内部错误如果不设置
.catch()会被静默吞掉 - 链式调用仍然不如同步代码直观
- 调试不便,无法像同步代码一样设置断点逐步调试
- 多个
.then()仍然会产生一定的嵌套感
适用场景:
- 网络请求(fetch、axios)
- 文件操作
- 定时器封装
- 需要组合多个异步操作的场景
- 现代前端/Node.js 项目的标准异步方案
Generator 函数
Generator 函数是 ES6 引入的,可以通过 yield 关键字暂停和恢复函数执行,天然适合处理异步流程。
javascript
function* fetchUser() {
try {
const user = yield fetch('/api/user').then(r => r.json())
console.log('User:', user)
const posts = yield fetch(`/api/posts?userId=${user.id}`).then(r =>
r.json()
)
console.log('Posts:', posts)
return posts
} catch (err) {
console.error('Error:', err)
}
}
// 手动执行 Generator
const gen = fetchUser()
gen.next().value.then(user => {
gen.next(user).value.then(posts => {
gen.next(posts)
})
})
// 使用执行器自动执行
function run(generator) {
const gen = generator()
function step(arg) {
let result
try {
result = gen.next(arg)
} catch (err) {
return Promise.reject(err)
}
if (result.done) return Promise.resolve(result.value)
return Promise.resolve(result.value).then(step, err =>
step(Promise.reject(err))
)
}
return step()
}
run(fetchUser).then(console.log)优点:
- 异步代码看起来像同步代码,可读性极佳
- 拥有完整的函数语义(函数名、参数、返回值)
- 可以暂停执行,实现惰性求值
- 支持双向通信(通过
next()传值和yield返回值) - 灵活性高,可以手动控制执行流程
- 是 async/await 的底层实现基础
缺点:
- 需要额外的执行器(co、run)才能自动管理异步流程
- 学习曲线陡峭,概念较多(Iterator Protocol、yield、next)
- 手动执行时代码仍然复杂
- 与其他异步方案混用时容易混乱
- 调试支持不如 async/await
- 实际开发中已被 async/await 大量替代
适用场景:
- 惰性序列生成(如斐波那契数列、无限序列)
- 异步流程控制库的底层实现
- 需要精细控制执行步骤的场景
- 实现迭代器模式
async / await
async/await 是 ES2017 引入的语法糖,基于 Promise 实现,让异步代码看起来和同步代码完全一致。
javascript
async function fetchUserData() {
try {
const userResponse = await fetch('/api/user')
const user = await userResponse.json()
const postsResponse = await fetch(`/api/posts?userId=${user.id}`)
const posts = await postsResponse.json()
return { user, posts }
} catch (err) {
console.error('Failed to fetch user data:', err)
throw err
}
}
// 并行执行
async function fetchAllData() {
try {
const [users, posts] = await Promise.all([
fetch('/api/users').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
])
return { users, posts }
} catch (err) {
console.error(err)
}
}
// 顶层 await(ES2022)
const data = await fetch('/api/data').then(r => r.json())优点:
- 代码可读性最佳,几乎与同步代码一致
- 支持标准的 try/catch 错误处理
- 调试友好,可以像同步代码一样设置断点
- 语法简洁,学习成本低
- 与 Promise 完全兼容,可以混用
- 现代浏览器和 Node.js 全面支持
- 支持顶层 await(ES2022)
缺点:
- 连续的 await 会串行执行,可能影响性能(需要手动用 Promise.all 并行化)
- 错误堆栈可能不如纯 Promise 清晰
- 在循环中使用 await 可能导致性能问题
- 无法取消(继承自 Promise 的限制)
- 不适合事件驱动的持续异步流
适用场景:
- 现代前端和 Node.js 项目的首选异步方案
- 需要顺序执行多个异步操作
- 需要 try/catch 错误处理的场景
- API 调用、数据库操作等常规异步任务
- React Hooks 中的数据获取
Promise 静态方法进阶
ES2020 引入了 Promise.allSettled 和 Promise.any,与 ES6 的 Promise.all 和 Promise.race 一起提供了丰富的异步编排能力。
javascript
// Promise.all - 全部成功才成功,一个失败即失败
const results = await Promise.all([
fetch('/api/user').then(r => r.json()),
fetch('/api/posts').then(r => r.json())
])
// Promise.allSettled - 等待全部完成(无论成功失败)
const settled = await Promise.allSettled([
fetch('/api/service1').then(r => r.json()),
fetch('/api/service2').then(r => r.json()),
fetch('/api/service3').then(r => r.json())
])
settled.forEach(result => {
if (result.status === 'fulfilled') {
console.log('Success:', result.value)
} else {
console.log('Failed:', result.reason)
}
})
// Promise.any - 任意一个成功即成功
const fastest = await Promise.any([
fetch('/api/cdn1/data').then(r => r.json()),
fetch('/api/cdn2/data').then(r => r.json()),
fetch('/api/cdn3/data').then(r => r.json())
])
// Promise.race - 任意一个完成(成功或失败)即返回
const raceResult = await Promise.race([
fetch('/api/data').then(r => r.json()),
new Promise((_, reject) =>
setTimeout(() => reject(new Error('Timeout')), 3000)
)
])优点:
Promise.all:适合需要所有异步操作都成功的场景Promise.allSettled:适合需要知道每个操作结果的场景,不会因为某个失败而中断Promise.any:适合冗余请求、竞速获取最快响应的场景Promise.race:适合超时控制、竞速场景
缺点:
Promise.all:一个失败全部失败,无法获取成功的结果Promise.allSettled:需要手动判断每个结果的状态Promise.any:所有都失败时返回 AggregateError,处理较复杂Promise.race:无法取消其他未完成的 Promise(可能导致资源浪费)
适用场景:
Promise.all:批量数据加载、并行 API 请求Promise.allSettled:批量操作容错、健康检查Promise.any:CDN 竞速、多数据源容灾Promise.race:请求超时控制
异步迭代器(Async Iterator)
ES2018 引入了异步迭代器和 for await...of 循环,用于处理异步数据流。
javascript
// 异步生成器
async function* fetchPaginatedData(url) {
let page = 1
while (true) {
const response = await fetch(`${url}?page=${page}`)
const data = await response.json()
if (data.items.length === 0) break
yield data.items
page++
}
}
// for await...of 消费异步迭代器
async function processAllPages() {
for await (const items of fetchPaginatedData('/api/posts')) {
console.log(`Processing ${items.length} items`)
items.forEach(item => processItem(item))
}
}
// Node.js Readable Stream 异步迭代
const fs = require('fs')
const readline = require('readline')
async function processFile(filePath) {
const stream = fs.createReadStream(filePath)
const rl = readline.createInterface({ input: stream })
for await (const line of rl) {
console.log('Line:', line)
}
}优点:
- 天然处理分页、流式数据等持续产生的异步数据
- 与
for...of语法一致,学习成本低 - 支持惰性求值,按需加载数据
- 与 Node.js Stream 完美结合
- 内存效率高,不需要一次性加载所有数据
缺点:
- 浏览器支持相对较新(IE 完全不支持)
- 错误处理需要在循环外部 try/catch
- 无法直接并行处理(每次只处理一个元素)
- 调试异步生成器比较困难
- 中断循环需要使用 break 或 throw
适用场景:
- 分页数据加载
- Node.js Stream 处理
- SSE(Server-Sent Events)消费
- WebSocket 消息流处理
- 大文件逐行读取
Web Workers
Web Workers 允许在后台线程中运行 JavaScript,不会阻塞主线程,适合处理 CPU 密集型任务。
javascript
// 主线程 main.js
const worker = new Worker('worker.js')
worker.postMessage({ type: 'start', data: largeDataSet })
worker.onmessage = function (e) {
console.log('Result from worker:', e.data)
}
worker.onerror = function (err) {
console.error('Worker error:', err)
}
// worker.js
self.onmessage = function (e) {
if (e.data.type === 'start') {
const result = heavyComputation(e.data.data)
self.postMessage({ type: 'result', data: result })
}
}
function heavyComputation(data) {
// 耗时计算...
return processedData
}优点:
- 不阻塞主线程,保持 UI 流畅
- 真正的并行计算,利用多核 CPU
- 独立的运行环境,不影响主线程变量
- 适合 CPU 密集型任务(图像处理、数据分析等)
- 支持多个 Worker 并行
缺点:
- 无法直接操作 DOM
- 通信开销(通过 postMessage 序列化/反序列化)
- 创建 Worker 有性能开销,不适合短任务
- 调试困难(Chrome DevTools 支持有限)
- 同源限制,Worker 脚本必须与主页面同源
- 增加了代码复杂度
适用场景:
- 大数据计算和分析
- 图像/视频处理
- 加密/解密操作
- 复杂的数学运算
- 文件处理(如 CSV/JSON 大文件解析)
RxJS(响应式编程)
RxJS 是 Reactive Extensions 的 JavaScript 实现,使用 Observable 序列来处理异步数据流和事件组合。
javascript
import { fromEvent, debounceTime, map, switchMap, catchError, of } from 'rxjs'
import { ajax } from 'rxjs/ajax'
// 搜索框自动补全
const searchInput = document.getElementById('search')
fromEvent(searchInput, 'input')
.pipe(
debounceTime(300),
map(event => event.target.value),
switchMap(query =>
ajax.getJSON(`/api/search?q=${query}`).pipe(catchError(() => of([])))
)
)
.subscribe(results => {
renderResults(results)
})
// 定时器
import { interval, take, filter } from 'rxjs'
interval(1000)
.pipe(
take(5),
filter(value => value % 2 === 0)
)
.subscribe(value => console.log(value)) // 0, 2, 4优点:
- 强大的数据流处理能力,支持丰富的操作符
- 内置背压处理、取消订阅等机制
- 声明式编程,代码简洁
- 完美处理高频事件(如搜索输入、滚动、窗口调整)
- 支持复杂的异步操作组合
- 错误处理和重试机制完善
缺点:
- 学习曲线非常陡峭,概念众多(Observable、Observer、Subject、Operator 等)
- 调试困难,数据流不透明
- 库体积较大(即使 tree-shaking 后也有一定体积)
- 过度使用会导致代码可读性下降
- 团队协作时需要所有成员都熟悉 RxJS
- 在简单场景下显得过于复杂
适用场景:
- 高频事件处理(搜索、滚动、拖拽)
- 复杂的异步数据流组合
- 实时数据推送(WebSocket、SSE)
- Angular 项目(Angular 内置使用 RxJS)
- 需要取消、重试、节流等复杂控制的场景
Node.js Stream
Node.js Stream 是处理流式数据的异步方案,支持四种流类型:Readable、Writable、Duplex、Transform。
javascript
const fs = require('fs')
const { pipeline } = require('stream/promises')
const { Transform } = require('stream')
// 文件复制
async function copyFile(src, dest) {
await pipeline(fs.createReadStream(src), fs.createWriteStream(dest))
}
// 数据转换流
const upperCase = new Transform({
transform(chunk, encoding, callback) {
callback(null, chunk.toString().toUpperCase())
}
})
fs.createReadStream('input.txt')
.pipe(upperCase)
.pipe(fs.createWriteStream('output.txt'))
// 异步迭代器方式消费
async function processStream() {
const stream = fs.createReadStream('large-file.txt', {
highWaterMark: 64 * 1024
})
stream.setEncoding('utf-8')
for await (const chunk of stream) {
console.log('Chunk:', chunk)
}
}优点:
- 内存效率极高,不需要一次性加载全部数据
- 支持背压机制,自动调节数据流速
- 可以通过
.pipe()优雅地组合多个流 - 适合处理大文件和网络数据
- Node.js 核心模块,无需额外依赖
缺点:
- 仅限 Node.js 环境,浏览器不直接支持
- 错误处理比较复杂(尤其是管道中的错误传播)
- 调试困难,数据在管道中流动不透明
- 某些流类型(如 Transform)编写较复杂
- 旧版 Node.js 的 Stream API 与新版不完全兼容
适用场景:
- 大文件读写和处理
- 网络数据传输(HTTP 请求/响应)
- 日志处理
- 数据压缩/解压
- 视频音频处理
定时器(setTimeout / setInterval)
JavaScript 的定时器是最简单的异步机制,用于延迟或重复执行代码。
javascript
// setTimeout - 延迟执行
setTimeout(() => {
console.log('Executed after 1 second')
}, 1000)
// setInterval - 重复执行
const timer = setInterval(() => {
console.log('Executed every second')
}, 1000)
// 清除定时器
clearInterval(timer)
// setTimeout 模拟 setInterval(避免重叠)
function repeat(fn, delay) {
setTimeout(function loop() {
fn()
setTimeout(loop, delay)
}, delay)
}
// Promise 化定时器
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms))
}
async function main() {
console.log('Start')
await delay(1000)
console.log('After 1 second')
}优点:
- API 简单,使用方便
- 所有 JavaScript 环境都支持
- 适合简单的延时和轮询场景
- 与 Promise 结合使用非常灵活
缺点:
- 最小延迟约 4ms(浏览器中嵌套超过 5 层时)
- 不保证精确的时间间隔(受事件循环影响)
setInterval可能出现回调重叠问题- 在非活动标签页中,浏览器可能降低定时器精度(甚至暂停)
- 不适合需要精确计时的场景
适用场景:
- 简单的延时操作
- 轮询检查状态
- 动画和视觉效果
- 防抖/节流的底层实现
- 超时控制
requestAnimationFrame
requestAnimationFrame 是浏览器提供的专门用于动画的异步 API,会在下一次重绘之前调用指定的回调函数。
javascript
// 基本动画
function animate() {
// 更新动画状态
update()
// 重绘
draw()
// 下一帧继续
requestAnimationFrame(animate)
}
requestAnimationFrame(animate)
// Promise 化
function nextFrame() {
return new Promise(resolve => requestAnimationFrame(resolve))
}
async function smoothScroll(element, target) {
while (Math.abs(element.scrollTop - target) > 1) {
element.scrollTop += (target - element.scrollTop) * 0.1
await nextFrame()
}
element.scrollTop = target
}优点:
- 与浏览器刷新率同步(通常 60fps),动画流畅
- 在标签页不可见时自动暂停,节省资源
- 浏览器会自动优化渲染时机
- 比 setTimeout 动画性能更好、更流畅
缺点:
- 仅限浏览器环境
- 回调函数只接收一个 timestamp 参数
- 无法指定延迟时间
- 不适合非动画类的异步操作
适用场景:
- Canvas 动画
- DOM 动画(滚动、过渡效果)
- 游戏循环
- 视觉效果和粒子系统
MutationObserver
MutationObserver 是浏览器提供的用于监视 DOM 变化的异步 API。
javascript
const observer = new MutationObserver(mutations => {
mutations.forEach(mutation => {
switch (mutation.type) {
case 'childList':
console.log('Child nodes changed')
break
case 'attributes':
console.log(`Attribute ${mutation.attributeName} changed`)
break
case 'characterData':
console.log('Text content changed')
break
}
})
})
observer.observe(targetNode, {
childList: true,
attributes: true,
characterData: true,
subtree: true
})
// 停止观察
observer.disconnect()优点:
- 异步批量处理 DOM 变化,性能优于 Mutation Events
- 可以精确配置观察范围(子节点、属性、文本等)
- 支持获取变化记录的详细信息
- 不会阻塞 DOM 操作
缺点:
- 仅限浏览器环境
- API 相对复杂
- 在大量 DOM 变化时可能产生性能问题
- 需要手动 disconnect 避免内存泄漏
适用场景:
- 监听第三方库对 DOM 的修改
- 实现自定义组件的响应式更新
- 调试 DOM 变化
- 实现虚拟 DOM 的差异检测
IntersectionObserver
IntersectionObserver 用于异步观察目标元素与其祖先元素或顶级文档视口的交叉状态。
javascript
const observer = new IntersectionObserver(
entries => {
entries.forEach(entry => {
if (entry.isIntersecting) {
console.log('Element is visible')
loadContent(entry.target)
observer.unobserve(entry.target)
}
})
},
{
root: null,
threshold: 0.1,
rootMargin: '100px'
}
)
document.querySelectorAll('.lazy-load').forEach(el => {
observer.observe(el)
})优点:
- 性能远优于监听 scroll 事件 + getBoundingClientRect
- 异步执行,不阻塞主线程
- 浏览器内部优化,无需手动计算
- 配置灵活(阈值、根元素、边距)
缺点:
- 仅限浏览器环境
- 无法获取精确的滚动位置
- 兼容性:IE 不支持(需要 polyfill)
- 某些复杂场景(如水平滚动嵌套)支持有限
适用场景:
- 图片懒加载
- 无限滚动
- 元素曝光统计
- 广告可见性检测
- 滚动动画触发
AbortController(取消异步操作)
AbortController 是现代浏览器和 Node.js 提供的用于取消异步操作的 API。
javascript
// 取消 fetch 请求
const controller = new AbortController()
const signal = controller.signal
fetch('/api/data', { signal })
.then(response => response.json())
.then(data => console.log(data))
.catch(err => {
if (err.name === 'AbortError') {
console.log('Request was cancelled')
} else {
console.error(err)
}
})
// 3 秒后取消
setTimeout(() => controller.abort(), 3000)
// 取消多个请求
function createFetchWithTimeout(url, timeout = 5000) {
const controller = new AbortController()
const id = setTimeout(() => controller.abort(), timeout)
return fetch(url, { signal: controller.signal }).finally(() =>
clearTimeout(id)
)
}优点:
- 标准化的取消机制,可取消 fetch、EventTarget 监听等
- 避免不必要的网络请求和资源消耗
- 支持取消多个关联的异步操作
- 与 Promise、EventTarget 等原生 API 深度集成
缺点:
- 需要异步 API 显式支持 signal 参数
- 一旦取消不可恢复
- 兼容性:IE 不支持,旧版浏览器需要 polyfill
- 需要手动管理 AbortController 生命周期
适用场景:
- 取消未完成的 fetch 请求
- 搜索输入时的请求去重(取消上一次请求)
- 组件卸载时清理异步操作
- 请求超时控制
- 用户主动取消长时间操作
各方案对比总结
| 方案 | 引入版本 | 可读性 | 错误处理 | 取消支持 | 适用环境 | 学习成本 |
|---|---|---|---|---|---|---|
| 回调函数 | ES3 | 差 | 差 | 需手动 | 全部 | 低 |
| 事件监听 | DOM Level 2 | 中 | 中 | 需手动 | 浏览器/Node.js | 低 |
| 发布订阅 | 自定义实现 | 中 | 中 | 需手动 | 全部 | 中 |
| Promise | ES6 | 好 | 好 | 不支持 | 全部 | 中 |
| Generator | ES6 | 好 | 好 | 支持 | 全部 | 高 |
| async/await | ES2017 | 最佳 | 最佳 | 不支持 | 全部 | 低 |
| Promise 静态方法 | ES2020 | 好 | 好 | 不支持 | 全部 | 中 |
| 异步迭代器 | ES2018 | 好 | 好 | break | 全部 | 中 |
| Web Workers | HTML5 | 中 | 中 | terminate | 浏览器 | 高 |
| RxJS | 第三方库 | 中 | 好 | unsubscribe | 全部 | 很高 |
| Node.js Stream | Node.js 核心 | 中 | 中 | destroy | Node.js | 高 |
| 定时器 | ES3 | 好 | 差 | clearTimeout | 全部 | 低 |
| requestAnimationFrame | 浏览器 API | 好 | 差 | cancelAnimationFrame | 浏览器 | 低 |
| MutationObserver | DOM Level 4 | 中 | 中 | disconnect | 浏览器 | 中 |
| IntersectionObserver | 浏览器 API | 好 | 中 | unobserve | 浏览器 | 中 |
| AbortController | DOM/Node.js | 好 | 好 | abort | 全部 | 低 |