关于对Promise

102 阅读3分钟

rfwDB3L.png Promise 是 JavaScript 中的一种异步编程方式,可以优雅地解决回调地狱问题,提高代码可读性和可维护性,是 JavaScript 开发中必备的技术之一。我将介绍 Promise 的基本原理和用法。

Promise 原理

Promise 本质上是一种对象 - 即异步操作的一个句柄(或占位符),在某个异步操作完成(或失败)之后会被替换成异步操作的结果(或错误)。一个 Promise 的状态只能从初始化为进行中,完成或失败。

Promise 有以下三种状态:

  1. Pending: 初始状态,既不是成功,也不是失败状态。

  2. Fulfilled: 意味着操作成功完成,Promise 对象传递给 then 方法的回调函数参数是成功完成的结果。

  3. Rejected: 意味着操作失败,Promise 对象传递给 then 方法的回调函数参数是失败的原因。

Promise 用法

Promise 用法分为以下两部分: 创建 Promise 和 Promise 的状态修改。

创建 Promise

我们可以使用 Promise 构造函数来创建一个 Promise 对象:

const promise = new Promise((resolve, reject) => {
  // 异步操作任务
  // 如果成功,则调用 resolve 方法将结果传递出去
  // 如果失败,则调用 reject 方法将失败原因传递出去
});

在 Promise 构造函数中,我们执行异步任务,如果成功完成任务,则调用 resolve 方法将结果返回,否则调用 reject 方法将失败原因返回。

Promise 状态修改

我们可以通过 thencatchfinally 等方法来处理 Promise 对象的状态。

  • then: 在 Promise 成功时调用,接收一个处理成功的回调函数。

  • catch: 在 Promise 失败时调用,接收一个处理失败的回调函数。

  • finally: 不管 Promise 成功或失败,都会执行该方法中的任务。

promise
  .then(result => {
    // 处理 successfulResult
  })
  .catch(error => {
    // 处理 failureReason
  })
  .finally(() => {
    // 无论成功或失败都会执行的逻辑
  });

以上方法都是可以链式调用的。例如,我们可以使用 then 方法获取 Promise 对象的成功处理结果,然后再使用 catch 方法处理失败情况:

promise
  .then(result => {
    // 处理 successfulResult
  })
  .catch(error => {
    // 处理 failureReason
  });

Promise 示例

我们来通过一个示例代码来深入理解 Promise 的用法。

假设我们有一个异步获取用户信息的方法 getUserInfo,我们可以通过 Promise 来实现异步调用:

function getUserInfo(userId) {
  return new Promise((resolve, reject) => {
    // 异步获取用户信息
    setTimeout(() => {
      const users = {
        1: { name: 'Alice' },
        2: { name: 'Bob' }
      };
      const user = users[userId];
      if (user) {
        resolve(user);
      } else {
        reject(`User with ID ${userId} not found`);
      }
    }, 1000);
  });
}

在上述代码中,getUserInfo 方法通过 Promise 包装了异步任务,具体实现如下所示:

  • 如果找到了对应用户,调用 resolve 并传递用户信息。

  • 如果没找到,调用 reject 并传递错误信息。

接着,我们可以在 vue 组件中使用该方法来展示用户信息:

<template>
  <div>
    <label>User ID:</label>
    <input type="text" v-model="userId">
    <button @click="getUser">Get User</button>
    <div v-if="user">
      <h1>Hello, {{ user.name }}!</h1>
    </div>
    <div v-else-if="isLoading">Loading...</div>
    <div v-else>
      <p>User not found!</p>
    </div>
  </div>
</template>

我认为的关键点是:

  1. 三个状态 pending fulfilled rejected pending 等待中, 默认创建出来的状态 fulfilled 已完成 rejected 失败

  2. 回调中接收两个方法 resolve reject 调用resolve方法, 将promise状态从pending改成fulfilled, 将来执行.then resolve(xxx)

    调用reject方法, 将promise状态从pending改成rejected, 将来执行.catch reject(xxx)

  3. 能够使用 promise 对异步操作进行包装 (懂promise的语法)

  4. const p = new Promise((resolve, reject) => {
       // 异步操作
       // 异步操作成功 resolve(值)
       // 异步操作失败 reject(值)
    })
    
    p.then(xxx => {}).catch(xxx => {})
    
    const res = await p