promise本身不提供调度能力,但可封装异步状态并通过链式调用实现串行依赖、all/allsettled实现并行批量、自定义队列加并发限制控制执行节奏。

Promise 本身不直接提供任务调度能力,但它是构建任务调度器的底层基石。处理复杂调度的关键,不是把 Promise 当作“定时器”或“计划表”,而是用它封装异步操作的状态,并通过组合、队列、并发控制等策略实现有序、可控的执行流程。
用 Promise 链实现串行依赖调度
当任务有明确先后依赖(比如 A 完成后才能启动 B,B 的输出是 C 的输入),Promise 链是最自然的选择。每个 .then() 返回新 Promise,天然形成执行顺序。
- 避免手动维护状态变量或回调嵌套,逻辑清晰可读
- 错误会自动沿链向下传递到最近的
.catch(),统一处理异常路径 - 注意:若某环节需条件分支(如“成功则走 C,失败则走 D”),应在
.then()或.catch()内部返回新的 Promise,而非直接写同步 if-else
用 Promise.all / allSettled 实现并行批量调度
多个独立任务(如同时拉取用户、订单、配置)适合并行发起,但需根据业务语义选对方法:
-
Promise.all([...]):全部成功才继续,任一失败即中断——适合强一致性场景(如表单提交前校验所有字段) -
Promise.allSettled([...]):无论成败都等待全部结束,返回每个结果的状态对象——适合容错型批量操作(如日志上报、多渠道通知) - 不要在循环里反复
await单个 Promise,那会退化为串行,失去并行收益
用自定义队列 + 并发限制控制执行节奏
真实业务常需“最多同时跑 3 个请求”,防止压垮服务端或浏览器连接数。这需要手写调度器,核心是:维护运行中数量 + 待执行队列 + 完成后自动触发下一个。
- 创建一个函数如
promiseLimit(limit),返回带add()方法的对象 - 每次
add(promiseFactory)不立即执行,而是推入队列;仅当当前运行数 promiseFactory() - 每个 Promise 结束后(
.finally()),递归检查队列是否还有任务,有则启动下一个 - GuzzleHttp 的
TaskQueue是 PHP 侧 FIFO 调度参考,JS 中可用数组 +shift()模拟
用 async/await + 状态管理应对动态流程
当调度逻辑本身是动态的(例如根据上一步结果决定下一步发几个请求、走哪条分支),纯链式会变得僵硬。此时应退回到 async/await + 显式控制流:
- 用
for...of遍历任务列表,内部await每个 Promise,便于插入条件判断和重试逻辑 - 配合 Map 或对象缓存中间结果,避免重复计算或请求
- 对关键步骤加超时保护:用
Promise.race([task, timeoutPromise])防止卡死











