CLASS 15 · 2026-04-06 · 14-16 并发
Promise
Promise 是「将来才会有结果」的信封。它让你不必阻塞等待,而是用 await 在结果就绪时再继续,同时用聚合函数把多个并发计算组合成新的逻辑。
Promise 是什么?
Promise:一个表示并发计算的对象,该计算已经启动,但结果可能尚未就绪。
Promise<T> 是一个可变值——它的状态会随时间改变,但持有的结果类型 T 由泛型保证。一个 Promise 有三种状态:
- 待定(pending):计算还在进行。
- 已完成(fulfilled):计算成功,带有结果值。
- 已拒绝(rejected):计算失败,带有错误。
await
await 关键字把一个 Promise<T>「打开」,变成 T。如果 Promise 还在待定状态,await 会让出控制权,让其他代码先跑,直到结果就绪再恢复。
async function fetchUser(id: number): Promise<User> {
const res = await fetch(`/api/users/${id}`); // 让出控制权
const data: User = await res.json();
return data;
}
异步函数
用 async 声明的函数是异步函数。它在计算完成前就把控制权交还给调用者,返回值自动包装成 Promise<T>。
async function greet(): Promise<string> {
return "hello";
}
// greet() 返回的是 Promise<string>,而非 string
JavaScript 的并发模型
TypeScript/JavaScript 在每个全局环境中只有一条控制线程。await 是唯一能让出控制权的地方——这让单线程上的多任务协作成为可能,也意味着长计算会阻塞整个事件循环。
聚合多个 Promise
Promise 提供了几种把多个并发计算组合成新逻辑的方式:
Promise.all(promises):等待全部完成(逻辑与),任一失败则整体失败。Promise.any(promises):等待任意一个完成(逻辑或),全部失败才失败。Promise.race(promises):等待任意一个完成或拒绝,以第一个敲定者为准。
const [user, orders] = await Promise.all([
fetchUser(42),
fetchOrders(42),
]);
// 两个请求并发发出,全部完成后继续
永远不要忙等待
Promise 没有公开方法让你查询它当前处于哪种状态。你不能用一个循环反复检查「好了没」——那叫忙等待(busy-waiting),会浪费 CPU 并阻塞事件循环。正确做法永远是 await。
Promise 与异常处理
- 异步函数里抛出异常,会让返回的 Promise 进入已拒绝状态。
- 对已拒绝的 Promise 使用
await,会把异常重新抛出。
async function risky(): Promise<number> {
throw new Error("boom");
}
async function main() {
try {
await risky();
} catch (e) {
console.log("捕获到", e); // 正常捕获
}
}
关键要点
- 状态Promise 三种状态:pending、fulfilled、rejected。
- await打开 Promise,让出控制权直到结果就绪。
- async异步函数返回 Promise,是并发计算的入口。
- 聚合all(全部)、any(任一成功)、race(首个敲定)。
- 异常throw → rejected,await rejected → 抛出。
- 禁忙等没有状态查询方法,永远用 await。