async/await和Promise有哪些区别

2 阅读3分钟

async/await 和 Promise 都是处理异步操作的方式,但它们在语法和使用上有重要区别:

1. 本质关系

  • Promise:是异步编程的解决方案对象,代表一个异步操作的最终完成(或失败)及其结果值
  • async/await:是基于 Promise 的语法糖,让异步代码看起来像同步代码

2. 语法对比

Promise 写法

function fetchData() {
    return fetch('/api/data')
        .then(response => response.json())
        .then(data => {
            console.log(data);
            return data;
        })
        .catch(error => {
            console.error(error);
        });
}

async/await 写法

async function fetchData() {
    try {
        const response = await fetch('/api/data');
        const data = await response.json();
        console.log(data);
        return data;
    } catch (error) {
        console.error(error);
    }
} 

3. 主要区别

特性Promiseasync/await
代码结构链式调用(.then().catch())类似同步代码的线性结构
错误处理使用 .catch() 或第二个参数使用 try/catch 块
可读性回调嵌套可能较深(回调地狱)更清晰,易于理解流程
调试断点跳转可能不直观可以像同步代码一样调试
变量作用域每个 .then() 都是新作用域整个 async 函数共享作用域

4. 关键特点

Promise 特点:

  • 三种状态:pending、fulfilled、rejected
  • 状态一旦改变不可逆转
  • 可以并行处理多个异步操作(Promise.allPromise.race
  • 可以提前创建但不立即执行

async/await 特点:

  • async 函数总是返回一个 Promise
  • await 只能在 async 函数中使用
  • await 会暂停当前 async 函数的执行,直到 Promise 解决
  • 代码自上而下顺序执行,逻辑更清晰

5. 错误处理差异

// Promise 错误处理
promise
    .then(result => { /* 处理结果 */ })
    .catch(error => { /* 处理错误 */ });

// async/await 错误处理
async function example() {
    try {
        const result = await promise;
        // 处理结果
    } catch (error) {
        // 处理错误
    }
}

6. 性能考虑

  • async/await 本质上会被转换为 Promise 链
  • 现代 JavaScript 引擎对两者优化都很好
  • async/await 在某些场景下可能产生微小的额外开销(生成器转换)

7. 使用建议

适合 Promise 的场景:

// 并行执行多个异步操作
Promise.all([task1, task2, task3])
    .then(results => {
        // 同时处理所有结果
    });

// 竞速场景
Promise.race([fetch1, fetch2])
    .then(firstResult => {
        // 使用最先返回的结果
    });

适合 async/await 的场景:

// 有依赖关系的异步操作序列
async function processOrder(orderId) {
    const order = await getOrder(orderId);
    const user = await getUser(order.userId);
    const payment = await getPayment(order.paymentId);
    // 清晰的顺序执行逻辑
    return { order, user, payment };
}

8. 互相转换

// async/await 转换为 Promise 链
async function asyncExample() {
    const a = await task1();
    const b = await task2(a);
    return b;
}
// 等价于
function promiseExample() {
    return task1()
        .then(a => task2(a));
}

// Promise 链转换为 async/await
promise
    .then(value => process(value))
    .then(result => console.log(result));
// 转换为
async function handlePromise() {
    const value = await promise;
    const result = await process(value);
    console.log(result);
}

总结

  • Promise 是基础,async/await 是建立在 Promise 之上的语法糖
  • async/await 让代码更易读,特别适合处理有顺序依赖的异步操作
  • Promise 更适合并行处理多个独立的异步任务
  • 两者可以混合使用,根据具体场景选择最合适的方式

实际开发中,通常会结合使用两种方式,利用各自的优势来编写更清晰、高效的异步代码。