MST

星途 面试题库

面试题:Node.js 中 Promise 与 async/await 的深入比较及优化选择

在 Node.js 开发中,Promise 和 async/await 都用于处理异步操作。请详细比较它们在语法、错误处理、性能以及代码可读性方面的差异,并阐述在何种复杂业务场景下,你会优先选择使用 async/await 而不是 Promise,以及原因。
30.6万 热度难度
前端开发Node.js

知识考点

AI 面试

面试题答案

一键面试

语法差异

  • Promise:通过.then()链式调用处理异步操作的成功结果,通过.catch()捕获错误。例如:
function asyncFunction() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('Success');
        }, 1000);
    });
}

asyncFunction()
  .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()
  • async/await:使用try...catch块捕获错误,await后的Promise如果被拒绝,错误会被catch捕获,更接近同步代码的错误处理方式。

性能差异

  • Promiseasync/await在性能上基本没有差异,因为async/await本质是基于Promise实现的语法糖。它们都是利用JavaScript的事件循环机制来处理异步操作。

代码可读性差异

  • Promise:链式调用在处理多个异步操作时,可能会导致代码横向扩展,变得冗长,尤其是在复杂嵌套时,出现“回调地狱”的变体。
  • async/await:代码结构更接近同步代码,await使得异步操作看起来像同步操作,提高了代码的可读性和可维护性。

优先选择async/await的场景及原因

  • 场景:在涉及多个异步操作,且这些操作之间存在顺序依赖,或者需要处理复杂的错误处理逻辑的场景。例如,一个电商应用中,需要先查询用户信息,根据用户信息查询购物车,再根据购物车计算总价等一系列顺序执行的异步操作。
  • 原因async/await的语法更简洁直观,能让开发者以同步编程的思维方式来处理异步操作,错误处理也更清晰,通过try...catch可以统一捕获所有await处的错误,使代码更易读、易维护。相比之下,Promise链式调用在处理复杂顺序依赖和错误处理时,代码可能变得复杂和难以理解。