likes
comments
collection
share

async/await与Promise配合——从基础到进阶实战

作者站长头像
站长
· 阅读数 26

前言

async/awaitPromise 都是JS异步编程中重要部分,他们的关系是十分紧密。深入理解二者的关系是我们提高异步处理能力必须具备的,下面我将深入探究async/awaitPromise的内在联系,揭示它们之间的关系和作用。

1. 语法糖和基础

  • Promise 是ES6引入的一种解决异步问题的原生对象,它代表一个异步操作的结果,这个结果可能已经完成、正在进行,或者还未开始。Promise通过.then().catch().finally()等方法链式调用来处理异步操作的成功或失败结果。
  • async/await 是ES8引入的基于Promise的更高层次的抽象,可以看作是Promise的语法糖。async关键字用于声明一个异步函数,而await关键字用于等待一个Promise的结果,使得异步代码能够以更加同步的方式编写,提高了代码的可读性和简洁性。

下面两个目的一样的Promise链式调用示例和async/await示例:

Promise 示例

function fetchUserData(userId) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (userId === 1) {
                resolve({ id: userId, name: "Alice" });
            } else {
                reject("User not found");
            }
        }, 1000);
    });
}
fetchUserData(1)
    .then(user => console.log(user))
    .catch(err => console.error(err));

async/await 示例

async function fetchAndPrintUserData(userId) {
    try {
        const user = await fetchUserData(userId);
        console.log(user);
    } catch (err) {
        console.error(err);
    }
}
fetchAndPrintUserData(1);

2. 返回Promise

  • async函数总是返回一个Promise。即使函数体没有显式返回任何值,它也会隐式返回一个resolved的Promise;如果函数体中有return语句,则返回的值会被包裹在一个resolved的Promise中;如果在函数体内抛出错误,则返回一个rejected的Promise。
async function returnPromiseExample() {
    return "Hello, World!";
}
returnPromiseExample().then(result => console.log(result)); // 输出: Hello, World!

3. 异常处理

  • 使用Promise时,需要通过.catch()来捕获异步操作中抛出的错误。
  • 使用async/await,可以像处理同步代码中的错误一样,使用try/catch语句块来捕获异常,这使得错误处理更加直观和易于理解。

4. 等待Promise

  • await 关键字只能在async函数内部使用,它会使代码暂停在该行,直到等待的Promise解析(resolve或reject),然后继续执行后续代码。这种方式避免了回调地狱,使得异步逻辑更像同步代码。

1.返回的Promise不做回应

async function AsyncOperation() {
  return new Promise((resolve, reject)=>{
    console.log('无resolve, reject回应')
  })
}

async function awaitPromise() {
    const res ='111'
    const data = await someAsyncOperation();
    console.log(res);
    console.log(data);
}

我们可以看到await后面的res也未被打印出。 async/await与Promise配合——从基础到进阶实战

2.返回resolve

  async function someAsyncOperation() {
  return new Promise((resolve, reject)=>{
    resolve('resolved')
  })
}

  async function waitForPromiseExample() {
    const res ='111'
    const data = await someAsyncOperation();
    console.log(res);
    console.log(data);
}

当await得到了一个已回复的Promise对象,那么await在返回之后直接执行后面的语句。 async/await与Promise配合——从基础到进阶实战

5. 流控制

  • async/await 提供了更自然的流程控制机制,使得条件语句、循环等结构能更容易地应用于异步操作中,而不需要像使用Promise那样通过嵌套 .then() 来实现复杂的逻辑控制。
async function AsyncFunc1() {
    await new Promise(resolve => setTimeout(resolve, 1000)); 
    return "Result from AsyncFunc1";
}

async function AsyncFunc2() {
    await new Promise(resolve => setTimeout(resolve, 1500));
    return "Result from AsyncFunc2";
}
// 主异步函数,根据条件选择执行AsyncFunc1或AsyncFunc2
async function AsyncFunc() {
    const condition = true; // 条件
    let result;

    if (condition) {
        result = await AsyncFunc1();
    } else {
        result = await AsyncFunc2();
    }

    console.log(result);// 输出:Result from AsyncFunc1
}
AsyncFunc();

6. 兼容和互换性

  • Promise 有更广泛的浏览器和环境支持,因为它是ES6的一部分,大多数现代浏览器和Node.js环境都支持。
  • async/await 基于Promise构建,因此在支持async/await的环境中也可以直接使用Promise。同时,可以通过将Promise包装在async函数中,或者使用.then().catch()来“转换”async/await风格的代码为Promise风格,保持良好的互操作性。
// Async/Await 版本
async function fetchDataAsync(id) {
    const response = await fetch(`https://api.example.com/data/${id}`);
    return response.json();
}
// Promise 版本
function fetchDataPromise(id) {
    return fetch(`https://api.example.com/data/${id}`)
        .then(response => response.json());
}
// 两者可互换使用
fetchDataAsync(1).then(data => console.log(data));
fetchDataPromise(1).then(data => console.log(data));

可以看到返回的两个请求是一模一样的。 async/await与Promise配合——从基础到进阶实战

总结

async/await是基于Promise设计的高级语法,旨在简化异步代码的编写,提供一种更为直观和易于阅读的编程模型。本质上,async/await是对Promise的封装和升级,允许以同步的方式编写异步逻辑,而实际上这些操作仍然是非阻塞的。

当使用async/await时,开发者可以借助await关键字等待Promise的解决,使得代码在视觉上按照从上至下的顺序执行,无需链式.then()回调。同时,通过在async函数中使用标准的try...catch语句,可以更自然地处理异步操作中可能发生的错误,这与在Promise链中使用.catch()方法相比,更加贴近同步编程的习惯。

转载自:https://juejin.cn/post/7388714402168389669
评论
请登录