现在位置: 首页 > TypeScript 教程 > 正文

TypeScript Promise 详解

Promise 是 JavaScript 异步编程的基础,TypeScript 对 Promise 有完整的类型支持。

通过泛型参数,可以精确地指定 Promise 解决值和拒绝值的类型。


Promise 工作流程 创建 Promise new Promise((resolve, reject) => {...}) pending 等待中 fulfilled ✓ rejected ✗ then() · catch() · finally()

为什么需要 Promise

在 JavaScript 中,很多操作是异步的,如网络请求、文件读取、定时器等。

Promise 提供了统一的异步编程接口,让异步代码更容易编写和管理。

TypeScript 通过泛型支持,让 Promise 的类型安全得到了保障。

概念说明:Promise 是一个对象,表示一个异步操作的最终结果。它有三种状态:pending(进行中)、fulfilled(已成功)、rejected(已失败)。


创建 Promise

使用 Promise 构造函数创建 Promise,传入执行器函数。

实例

// 创建 Promise,使用泛型指定解决值的类型
// Promise<string> 表示成功时返回字符串
var promise = new Promise<string>(function(resolve, reject) {
    var success = true;
    if (success) {
        // 调用 resolve 表示操作成功,传入结果值
        resolve("成功!");
    } else {
        // 调用 reject 表示操作失败,传入错误
        reject(new Error("失败"));
    }
});

// 使用 then 处理成功情况
promise.then(function(value) {
    console.log("完成: " + value);
})["catch"](function(error) {
    // 使用 catch 处理失败情况
    console.log("错误: " + error.message);
});

运行结果:

完成: 成功!

泛型说明:Promise<T> 中的 T 是 Promise 成功解决时的值的类型。这让 TypeScript 能够推断返回值的类型。


Promise 链式调用

then 和 catch 方法返回新的 Promise,可以链式调用。

实例

// 链式调用:每个 then 返回新的值,被下一个 then 接收
var promise = Promise.resolve(1)
    .then(function(n) {
        // 第一个 then,n = 1
        return n * 2;  // 返回 2
    })
    .then(function(n) {
        // 第二个 then,n = 2
        return n + 10;  // 返回 12
    })
    .then(function(n) {
        // 第三个 then,n = 12
        console.log("最终结果: " + n);
        return n;
    });

console.log("Promise 链: " + promise);

运行结果:

最终结果: 12
Promise 链: [object Promise]

链式调用:每个 then 会返回一个新的 Promise,这允许我们按顺序执行多个异步操作。


Promise.all

Promise.all 等待所有 Promise 完成,返回一个包含所有结果的数组。

实例

// 创建三个 Promise
var p1 = Promise.resolve(1);
var p2 = Promise.resolve(2);
var p3 = Promise.resolve(3);

// Promise.all 等待所有 Promise 完成
// 返回一个数组,包含所有 Promise 的结果
Promise.all([p1, p2, p3]).then(function(results) {
    console.log("全部完成: " + results);
    // 计算总和
    console.log("总和: " + results.reduce(function(a, b) { return a + b; }, 0));
});

运行结果:

全部完成: 1,2,3
总和: 6

注意:如果任何一个 Promise 失败,Promise.all 会立即 rejection,不会等待其他 Promise 完成。


Promise.race

Promise.race 返回最先完成(无论成功或失败)的 Promise 的结果。

实例

// 创建三个不同延迟的 Promise
var p1 = new Promise(function(resolve) {
    setTimeout(function() { resolve("p1"); }, 100);
});
var p2 = new Promise(function(resolve) {
    setTimeout(function() { resolve("p2"); }, 50);
});
var p3 = new Promise(function(resolve) {
    setTimeout(function() { resolve("p3"); }, 30);
});

// Promise.race 返回最先完成的 Promise 的结果
Promise.race([p1, p2, p3]).then(function(value) {
    console.log("最先完成: " + value);
});

运行结果:

最先完成: p3

应用场景:Promise.race 常用于实现超时功能:把一个长时间操作的 Promise 和一个超时 Promise 竞争。


Promise.allSettled

Promise.allSettled 等待所有 Promise 结束(无论成功或失败),返回每个 Promise 的状态和结果。

实例

// 创建三个 Promise,其中一个会失败
var p1 = Promise.resolve("成功");
var p2 = Promise.reject(new Error("失败"));
var p3 = Promise.resolve("完成");

// Promise.allSettled 等待所有 Promise 结束
// 返回每个 Promise 的状态和值/reason
Promise.allSettled([p1, p2, p3]).then(function(results) {
    results.forEach(function(result, index) {
        if (result.status === "fulfilled") {
            console.log("Promise " + index + ": " + result.value);
        } else {
            console.log("Promise " + index + ": " + result.reason.message);
        }
    });
});

运行结果:

Promise 0: 成功
Promise 1: 失败
Promise 2: 完成

区别:Promise.all 会在第一个失败时立即停止;Promise.allSettled 会等待所有 Promise 结束。


Promise 类型注解

TypeScript 的泛型支持让 Promise 的类型声明变得精确。

实例

// 定义返回 Promise 的函数
// Promise<{ name: string; age: number }> 指定了返回的用户对象类型
function getUser(): Promise<{ name: string; age: number }> {
    return Promise.resolve({ name: "Alice", age: 25 });
}

// async 函数:隐式返回 Promise
async function main() {
    // await 会自动推断 user 的类型
    var user = await getUser();
    console.log("用户: " + JSON.stringify(user));
}

main();

类型推断:TypeScript 会根据泛型参数自动推断 Promise 的返回类型,这让我们在 async/await 中也能获得完整的类型提示。


注意事项

  • 泛型参数:始终为 Promise 指定泛型参数,明确返回类型
  • 错误处理:记得使用 catch 处理 Promise 失败的情况
  • all vs allSettled:需要全部结果时用 allSettled,需要快速失败时用 all
  • async/await:现代代码推荐使用 async/await,语法更简洁

最佳实践:优先使用 async/await 语法,它本质上还是基于 Promise,但写起来像同步代码。


总结

Promise 是 TypeScript 异步编程的核心。

  • Promise:异步操作容器,有 pending/fulfilled/rejected 三种状态
  • then/catch:链式处理异步结果
  • Promise.all:等待全部完成,任一失败则整体失败
  • Promise.race:返回最先完成的结果
  • Promise.allSettled:等待全部结束,返回每个的状态

建议:使用 async/await 语法配合 Promise,让异步代码既类型安全又易于阅读。

x