MST
星途 面试题库

面试题:Node.js中Promise和Async/Await在处理异步任务的差异及应用场景

详细说明Node.js中Promise和Async/Await在处理异步任务时,从语法、错误处理、性能以及适用场景等方面存在哪些差异?并举例说明在不同场景下如何选择使用它们。
44.5万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

语法差异

  • Promise:通过链式调用 .then().catch() 来处理异步操作的成功和失败。例如:
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('Success');
  }, 1000);
});
promise.then((result) => {
  console.log(result);
}).catch((error) => {
  console.error(error);
});
  • Async/Await:基于Promise,使用 async 定义异步函数,在函数内部使用 await 暂停函数执行,等待Promise解决。语法更简洁、同步化。例如:
async function asyncFunction() {
  try {
    const result = await new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('Success');
      }, 1000);
    });
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}
asyncFunction();

错误处理差异

  • Promise:通过链式调用末尾的 .catch() 捕获整个链中的错误。如果在某个 .then() 中没有处理错误,会传递到 .catch()。例如:
new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(new Error('Error'));
  }, 1000);
})
.then((result) => {
  console.log(result);
})
.catch((error) => {
  console.error(error);
});
  • Async/Await:使用 try...catch 块捕获错误,在 await 后的Promise被拒绝时,错误会被 catch 捕获。例如:
async function asyncFunction() {
  try {
    const result = await new Promise((resolve, reject) => {
      setTimeout(() => {
        reject(new Error('Error'));
      }, 1000);
    });
    console.log(result);
  } catch (error) {
    console.error(error);
  }
}
asyncFunction();

性能差异

  • Promise:Promise链中的任务按顺序执行,在一些复杂场景下,可能会因为链式调用过多而产生性能问题,特别是在大量的微任务堆积时。例如,一个很长的Promise链,每个.then都有一定计算量,会导致事件循环被长时间占用。
  • Async/Await:本质上和Promise性能差不多,因为它基于Promise。但由于语法简洁,代码可读性更好,更易于优化。例如,合理安排await的位置,可以避免不必要的等待,提高整体性能。同时,如果多个await之间没有依赖关系,可以使用Promise.all结合async/await并行执行任务,提升效率。

适用场景差异

  • Promise
    • 适用于多个异步操作相互依赖,需要链式调用处理结果的场景。比如先读取文件内容,然后根据内容进行网络请求,再处理请求结果。
    • 当需要在不同阶段添加不同的错误处理逻辑时,Promise的链式 .catch() 能更灵活地应对。例如在一个复杂的异步操作流程中,不同步骤可能出现不同类型的错误,在每个.then后可以针对性处理部分错误,最后再统一处理未捕获的错误。
  • Async/Await
    • 适用于需要以同步方式编写异步代码,使代码更易读的场景。特别是在处理多个异步操作,且这些操作不需要严格链式调用时,使用async/await搭配Promise.all可以并行执行多个异步任务,提高效率。比如同时发起多个网络请求获取数据,然后统一处理结果。
    • 在处理需要与同步代码紧密结合的异步操作时,async/await能让代码结构更清晰。例如在一个既有数据库查询(异步)又有简单数据计算(同步)的函数中,使用async/await可以将异步和同步部分更好地融合在一起。