async/await 本身不是状态机,但配合单一状态字段和语义化异步方法可构建高内聚异步状态机:用 status 枚举驱动 ui、封装状态跃迁为独立 async 方法、await 串起线性流程、class 封装状态与行为,使状态变更显式可控。

async/await 本身不是状态机,但它能让你用同步风格写异步逻辑,配合显式的状态管理(如状态字段 + 条件分支),就能自然构建高内聚、可读性强、易维护的异步状态机。
用一个单一状态字段驱动流程
避免分散判断多个 Promise 状态(pending/resolved/rejected),而是定义清晰的状态枚举(如 'idle'、'loading'、'success'、'error'),所有副作用和 UI 响应都基于这个字段响应:
- 状态变更统一走
this.status = 'xxx',不依赖 Promise 链中间态 - UI 渲染或副作用(如按钮禁用、加载动画)只监听
status,不重复检查isLoading、hasData、error多个布尔值 - 例如:
render() { switch(this.status) { case 'loading': return '⏳...'; case 'success': return this.data; } }
把每个状态转移封装成独立 async 方法
每个方法代表一次「状态跃迁」,职责明确、无副作用、可单独测试:
async load() { this.status = 'loading'; try { this.data = await fetch('/api'); this.status = 'success'; } catch (e) { this.status = 'error'; this.error = e; } }async retry() { if (this.status === 'error') await this.load(); }- 方法名体现意图(
load、submit、cancel),而非技术动作(fetchData)
用 await 链天然表达线性状态流,不用手动管理 Promise 链
当业务有明确步骤(如:校验 → 提交 → 轮询结果),直接用 await 串起多个状态方法,语义即流程:
async handleSubmit() { await this.validate(); await this.submit(); await this.pollResult(); }- 每一步失败都会自然中断后续,且错误可集中捕获(外层 try/catch)或按步骤分别处理
- 避免回调嵌套或
.then().then().catch()拆散状态逻辑
结合 class 封装状态 + 行为,实现高内聚
把状态字段、异步方法、重试策略、超时控制全部收进一个 class,对外只暴露语义化接口:
- 内部私有状态(
#status、#data、#abortController)不暴露给外部 - 提供
canSubmit这类计算属性(get canSubmit() { return this.#status === 'idle' || this.#status === 'error'; })代替外部逻辑判断 - 生命周期钩子可选(如
onStatusChange),但不强制——状态变更本身已足够驱动行为
不复杂但容易忽略:async/await 的真正优雅,不在语法简洁,而在它让「状态何时变、因何变、变成什么样」全部回归到开发者可读可控的代码路径中。状态机由此从隐式约定变成显式契约。











