TypeScript 中如何正确使用 Promise 和 async/await

阅读时长 6 分钟读完

在 Web 前端开发中,异步编程是必不可少的。JavaScript 原生的异步编程方式是通过回调函数,但这种方式容易导致回调函数嵌套过深,代码难以维护。Promise 是解决这个问题的一种方案,而 async/await 更进一步地简化了异步编程。而在 TypeScript 中使用 Promise 和 async/await,可以更好地规范和约束代码,提高代码的可读性和可维护性。

1. Promise

1.1 Promise 的基本使用

Promise 是一种异步编程的解决方案,它可以将异步操作以同步的方式来表达。Promise 对象有三种状态:pending(进行中)、resolved(已完成)和 rejected(已失败)。Promise 对象一旦进入 resolved 或 rejected 状态,就不会再改变状态。Promise 对象的状态改变只有两种可能:

  • 从 pending 变成 resolved;
  • 从 pending 变成 rejected。

Promise 对象的基本使用方式如下:

-- -------------------- ---- -------
----- ------- - --- ----------------- ------- -- -
  -- ----
  -- --- ------ --- -
    ---------- ---- ----
  - ---- -
    --------- ---- ----
  -
---

-------
  -------- ------ ---
  --------- ------ ---

其中,Promise 构造函数接受一个回调函数作为参数,该回调函数接受两个参数:resolve 和 reject,分别表示异步操作成功和失败的处理函数。then 方法和 catch 方法分别表示成功和失败的处理函数。then 方法可以链式调用,将上一步的处理结果传递到下一步的处理函数中。

1.2 Promise 和类型约束

在 TypeScript 中,Promise 和类型约束紧密相连。通过对 Promise 类型参数的约束,可以明确指定 Promise 对象的返回值类型,避免类型错误。Promise 类型参数的约束方式如下:

其中,Promise 构造函数的类型参数为 string,表示 Promise 对象返回的是一个字符串类型。Promise 的 resolve 方法接受一个字符串类型的参数,并且返回值是 undefined。reject 方法接受一个字符串类型的参数,并且返回值是 undefined。这样一来,我们使用 Promise 的时候就可以明确指定 Promise 对象的返回值类型了。

1.3 Promise.all 和 Promise.race

Promise.all 和 Promise.race 是 Promise 对象的两个常用方法。Promise.all 方法用于将多个 Promise 对象封装成一个 Promise 对象,只有当所有的 Promise 对象都成功时,Promise.all 才会返回成功状态。Promise.race 方法用于将多个 Promise 对象封装成一个 Promise 对象,只要有一个 Promise 对象成功,Promise.race 就会返回成功状态。Promise.all 和 Promise.race 的用法如下:

-- -------------------- ---- -------
---------------------- --------- ----------
  --------------- --------- -------- --------- -- -
    -- ------
  --
  --------------- ---- -- -
    -- ------
  ---

----------------------- --------- ----------
  -------------- ---- -- -
    -- ------
  --
  --------------- ---- -- -
    -- ------
  ---

其中,Promise.all 方法接受一个 Promise 对象数组作为参数,返回一个新的 Promise 对象。then 方法的结果集是一个数组,数组中的元素顺序和原数组中的顺序一一对应。Promise.race 方法接受一个 Promise 对象数组作为参数,返回一个新的 Promise 对象。then 方法的结果就是最先完成的那个 Promise 对象的结果。

2. async/await

2.1 async/await 的基本使用

async/await 是 ECMAScript 2017(ES8)的新特性,它可以让异步编程像同步编程一样简单。async/await 是 Promise 的语法糖,它基于 Promise 实现。async/await 的基本用法如下:

-- -------------------- ---- -------
----- -------- ----- -
  --- -------
  --- -
    ------ - ----- --------
  - ----- ------- -
    ---------------------
  -
  -- -- ------
-

其中,async 关键字定义了一个异步函数,该函数返回一个 Promise 对象。在异步函数中,可以使用 await 关键字暂停异步操作的执行,等待 Promise 对象返回结果。如果 Promise 对象返回成功结果,await 表达式的值就是该结果;如果 Promise 对象返回失败结果,await 表达式就会抛出错误。try...catch 块可以捕获异步函数的错误。

2.2 async/await 和类型约束

在 TypeScript 中,如何约束 async/await 的类型呢?下面是一个示例,展示如何使用 async/await 进行异步请求,并且将请求结果的类型作为约束限制:

-- -------------------- ---- -------
--------- -------- -
  ----- ----
-

----- -------- ------------ ----------------- -
  ----- -------- - ----- ---------------------------------
  ----- ---- - ----- ----------------
  ------ - ---- --
-

----- -------- ----- -
  ----- -------- - ----- ------------
  -- -- -------------
-

在这个示例代码中,fetchData 函数是一个异步函数,返回值是一个 Promise 对象,该对象的类型是泛型类型 Response。在 async 函数中,await 表达式的值类型就是约束类型 Response。

3. 总结

使用 Promise 和 async/await,可以更好地解决异步编程中的回调函数嵌套问题,提高代码可读性和可维护性。在 TypeScript 中使用 Promise 和 async/await,必须注意类型约束问题,以避免类型错误。在实际开发中,根据具体的业务场景和需求,可以选择使用 Promise 还是 async/await。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/6492a30148841e989406d779

纠错
反馈