Skip to content

Promise

一: Promise 简介

Promise是 JavaScript 中用于处理异步操作的一种机制,它提供了一种更清晰和可靠的方式来处理异步代码。Promise 有三个状态:pending(进行中)、fulfilled(已成功)和rejected(已失败),分别代表异步操作的不同阶段。

Promise 的工作原理:

  1. 创建 Promise 对象:

    • 使用 new Promise() 构造函数创建一个 Promise 对象。构造函数接受一个带有两个参数的执行函数,分别是 resolvereject
    javascript
    const myPromise = new Promise((resolve, reject) => {
      // 异步操作代码
      // 如果成功,调用 resolve(result)
      // 如果失败,调用 reject(error)
    });
  2. 状态转换:

    • Promise 对象的初始状态是 pending。在异步操作成功时,调用 resolve(result) 将状态转换为 fulfilled;在异步操作失败时,调用 reject(error) 将状态转换为 rejected
    javascript
    resolve(result); // 将状态转换为 fulfilled
    reject(error);   // 将状态转换为 rejected
  3. 处理结果:

    • 通过 .then() 方法处理异步操作成功的结果,通过 .catch() 方法处理异步操作失败的结果。这两个方法返回的都是 Promise 对象,可以链式调用。
    javascript
    myPromise.then((result) => {
      // 处理成功的结果
    }).catch((error) => {
      // 处理失败的结果
    });

使用 Promise 处理异步操作的示例:

javascript
function fetchData() {
  return new Promise((resolve, reject) => {
    // 模拟异步请求
    setTimeout(() => {
      const data = { name: 'John Doe', age: 25 };
      // 模拟请求成功
      resolve(data);
      // 模拟请求失败
      // reject(new Error('Failed to fetch data'));
    }, 2000);
  });
}

// 使用 Promise 处理异步操作
fetchData()
  .then((data) => {
    console.log('Data fetched successfully:', data);
    return data; // 将结果传递给下一个 .then() 或 .catch()
  })
  .then((data) => {
    console.log('Do something else with the data:', data);
  })
  .catch((error) => {
    console.error('Error:', error.message);
  });

在这个例子中,fetchData 函数返回一个 Promise 对象,通过 resolve 模拟异步请求成功,通过 reject 模拟异步请求失败。在使用时,通过 .then() 处理成功的结果,通过 .catch() 处理失败的结果。可以链式调用多个 .then() 来处理多个步骤的异步操作。这种方式使得异步代码更加清晰和易于维护。

二: async/await

async/await是 ECMAScript 2017(ES8)引入的一种异步编程的语法糖,用于更方便地处理 Promise 对象。它是建立在 Promise 基础上的一种语法,使异步代码的写法更加直观和类似于同步代码。

async/await 的作用:

  1. 更直观的异步代码:

    • async/await 使异步代码的写法更接近于同步代码,提高了代码的可读性。
  2. 处理 Promise 对象:

    • async 用于声明一个函数是异步的,返回的是一个 Promise 对象。await 用于等待 Promise 对象的解决(resolved)。

示例:

javascript
// 使用 Promise 处理异步操作
function fetchData() {
  return new Promise((resolve, reject) => {
    // 模拟异步请求
    setTimeout(() => {
      const data = { name: 'John Doe', age: 25 };
      // 模拟请求成功
      resolve(data);
      // 模拟请求失败
      // reject(new Error('Failed to fetch data'));
    }, 2000);
  });
}

// 使用 async/await 处理异步操作
async function fetchDataAsync() {
  try {
    const data = await fetchData(); // 等待 Promise 对象的解决
    console.log('Data fetched successfully:', data);
    // 可以在此处继续处理 data
  } catch (error) {
    console.error('Error:', error.message);
  }
}

// 调用异步函数
fetchDataAsync();

在这个例子中,fetchDataAsync 函数使用 async 关键字声明为异步函数,然后在函数体内使用 await 等待 fetchData 函数返回的 Promise 对象。通过 try/catch 来捕获可能的错误,使得异步代码的处理更为清晰。

关系与注意事项:

  1. 基于 Promise:

    • async/await 是建立在 Promise 基础上的,它本质上是对 Promise 的一层封装,提供更舒适的语法。
  2. 更直观的异步代码:

    • async/await 的语法糖使得异步代码更直观、易读,尤其是处理多个异步操作的情况。
  3. 错误处理:

    • 使用 try/catch 来捕获异步操作中的错误,与同步代码的错误处理更为一致。
  4. 只能在 async 函数内使用 await:

    • await 只能在 async 函数内部使用,如果在非异步函数中使用会导致语法错误。
javascript
// 正确的用法
async function myFunction() {
  const result = await someAsyncOperation();
  console.log(result);
}

// 错误的用法,会导致语法错误
function myFunction() {
  const result = await someAsyncOperation();
  console.log(result);
}

总体而言,async/await 是一种让异步代码更加清晰、易读的语法糖,特别适用于处理多个异步操作的情况。