← 返回目录

第 18 卷

第 18 / 19 卷日期:

生成器在异步编程中的核心优势:

  1. 异步逻辑同步化:代码结构与同步代码完全一致,无嵌套或链式调用,可读性极强;
  2. 错误处理直观:通过 try/catch 统一捕获所有yield异步操作的错误,与同步代码错误处理逻辑

一致;

  1. 灵活控制流程:可手动控制异步操作的执行顺序(通过手动调用next()),适合复杂的异步流程定

制。

注意:随着ES2017 async/await的出现,生成器已逐渐被替代。async/await本质是“生成器 + 自动执行器”的语法糖,无需依赖第三方库,使用更简洁,已成为现代异步编程的首选。

28. 详细描述async和await关键字的作用。它们与Promise相比有什么优

势和不同?

(1)async和await关键字的作用

async/await是ES2017引入的异步编程语法糖,基于Promise实现,核心作用是将异步逻辑“同步化”书写,进一步简化Promise的链式调用,让异步代码更易读、易维护。二者需配合使用,各自作用

如下:

  1. async关键字的作用
  2. 用于定义“异步函数”:在函数声明/表达式前加 async,标识该函数是异步函数(如 async

function fn() {}、 const fn = async () => {});

  1. 异步函数的返回值自动包装为Promise:无论函数内部返回什么值(原始值、对象),都会被

Promise.resolve() 包装为已成功的Promise;若函数内部抛出错误,则返回已失败的 Promise(错误原因为抛出的异常);

  1. 异步函数本身是“非阻塞”的:调用异步函数时,不会阻塞主线程,会立即返回一个Promise对

象,函数内部代码在后续事件循环中执行。

Code block

1 2// async函数返回值自动转为Promise

3async function asyncFn1() {

4return "成功结果"; //等价于return Promise.resolve("成功结果");
5}
6asyncFn1().then(result => console.log(result)); //输出:成功结果

11asyncFn2().catch(err => console.error(err.message)); // 输出:执行失败

  1. await关键字的作用
  2. 只能在async函数内部使用:若在非async函数中使用await,会直接报错;
  3. 暂停async函数执行,等待Promise完成: await 表达式中的“表达式”通常是一个Promise对

象(若不是,会被 Promise.resolve() 自动包装为Promise)。await会暂停当前async函数的执行,直到Promise状态改变(成功/失败);

  1. 返回Promise的成功结果,传递失败错误:若Promise成功,await会返回Promise的结果(resolve

的值),并恢复async函数执行;若Promise失败,await会将错误抛出(可通过try/catch捕获);

  1. 实现异步操作的顺序执行:多个await语句会按顺序依次执行,前一个await的Promise完成后,才

会执行下一个await,无需手动链式调用。

Code block

1 2// await暂停执行,等待Promise完成

3const fs = require("fs/promises");

4async function readFiles() { 5try {

6//按顺序执行异步操作,前一个完成后再执行下一个
7const data1 = await fs.readFile("file1.txt", "utf8");
8const data2 = await fs.readFile("file2.txt", "utf8");
9console.log("文件内容:", data1 + data2);
10} catch (err) {
11console.error("错误:", err.message); //捕获所有await的Promise错误
12}
13 }
14 readFiles();

(2)async/await与Promise的优势和不同

  1. 核心不同点
对比维度Promiseasync/await
语法形式基于对象和链式调用基于函数和关键字
代码结构多个异步操作顺序执行时,需多个异步操作顺序执行时,通
通过then链式调用,存过await按线性顺序书写,无
在“then链”冗余链式冗余,结构与同步代码一

致

错误处理通过catch方法统一捕获链直接使用try/catch块捕获
式调用中的错误,或在每个所有await的Promise错误,
then中传入第二个参数处与同步代码的错误处理逻辑完
理错误全一致,更直观
执行控制链式调用一旦发起,会按顺序await可手动控制每个异步操
自动执行,无法手动暂停单个作的执行时机(如在条件判断
异步操作的执行后使用await),流程控制更

灵活

学习成本需理解Promise的状态机制、基于同步代码思维,只需理
链式调用原理、静态方法解“await暂停等待
(all/race等),有一定学习Promise”,学习成本更低,
成本更易上手
  1. async/await相对Promise的优势
  2. 代码可读性更强:彻底消除Promise的链式调用冗余,异步逻辑按线性顺序书写,结构与同步代码

一致,降低了代码的理解成本,尤其适合复杂的多步骤异步流程。

  1. 错误处理更直观:无需记忆Promise的 catch 链式捕获规则,直接使用开发者熟悉的

try/catch 块处理错误,与同步代码的错误处理逻辑统一,减少错误遗漏。

  1. 流程控制更灵活:可在async函数内部通过条件判断、循环等逻辑控制await的执行时机,实现动态

的异步流程(如根据前一个异步结果决定是否执行下一个异步操作),而Promise的链式调用难以灵活实现此类逻辑。

  1. 调试更便捷:调试时可直接在await语句处打断点,暂停执行并查看当前状态;而Promise的链式调

用调试时,断点需要分散在多个 then 回调中,调试体验较差。

  1. 二者的关联与补充

async/await并非替代Promise,而是基于Promise的优化:

  1. async函数的返回值是Promise,因此async/await可与Promise的静态方法(如

Promise.all())配合使用,实现并行异步操作(多个await同时执行);

  1. 对于简单的异步操作(如单个网络请求),Promise的 then 链式调用足够简洁;对于复杂的多步
全站分卷索引 · 19 卷
  1. 1第 1 卷
  2. 2第 2 卷
  3. 3第 3 卷
  4. 4第 4 卷
  5. 5第 5 卷
  6. 6第 6 卷
  7. 7第 7 卷
  8. 8第 8 卷
  9. 9第 9 卷
  10. 10第 10 卷
  11. 11第 11 卷
  12. 12第 12 卷
  13. 13第 13 卷
  14. 14第 14 卷
  15. 15第 15 卷
  16. 16第 16 卷
  17. 17第 17 卷
  18. 18第 18 卷
  19. 19第 19 卷