CLASS 15 · 2026-04-06 · 14-16 并发

Promise

Promise 是「将来才会有结果」的信封。它让你不必阻塞等待,而是用 await 在结果就绪时再继续,同时用聚合函数把多个并发计算组合成新的逻辑。

Promise 是什么?

Promise:一个表示并发计算的对象,该计算已经启动,但结果可能尚未就绪。

Promise<T> 是一个可变值——它的状态会随时间改变,但持有的结果类型 T 由泛型保证。一个 Promise 有三种状态:

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 提供了几种把多个并发计算组合成新逻辑的方式:

const [user, orders] = await Promise.all([
  fetchUser(42),
  fetchOrders(42),
]);
// 两个请求并发发出,全部完成后继续

永远不要忙等待

Promise 没有公开方法让你查询它当前处于哪种状态。你不能用一个循环反复检查「好了没」——那叫忙等待(busy-waiting),会浪费 CPU 并阻塞事件循环。正确做法永远是 await

Promise 与异常处理

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。