Promise 是「将来才会有结果」的信封。它让你不必阻塞等待,而是用 await 在结果就绪时再继续,同时用聚合函数把多个并发计算组合成新的逻辑。
Promise:一个表示并发计算的对象,该计算已经启动,但结果可能尚未就绪。
Promise<T> 是一个可变值——它的状态会随时间改变,但持有的结果类型 T 由泛型保证。一个 Promise 有三种状态:
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
TypeScript/JavaScript 在每个全局环境中只有一条控制线程。await 是唯一能让出控制权的地方——这让单线程上的多任务协作成为可能,也意味着长计算会阻塞整个事件循环。
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。
await,会把异常重新抛出。async function risky(): Promise<number> {
throw new Error("boom");
}
async function main() {
try {
await risky();
} catch (e) {
console.log("捕获到", e); // 正常捕获
}
}