Promise的基本使用和概念

148 阅读3分钟

Promise 是 JavaScript 中的一种异步编程的解决方案。它代表了一个可能还未完成的操作的最终完成(或者失败)以及其结果值的表示。通过 Promise,你可以更清晰地处理异步操作(例如,网络请求、文件读取等),避免“回调地狱”问题,提升代码的可读性和维护性。

Promise 的基本概念

Promise 有三个状态:

  1. Pending(待定):初始状态,表示异步操作尚未完成。
  2. Fulfilled(已完成):表示异步操作已完成,成功返回结果。
  3. Rejected(已拒绝):表示异步操作失败,返回失败的原因。

Promise 构造函数

Promise 是一个构造函数,它接受一个执行器函数作为参数,执行器函数有两个参数:resolvereject

javascriptCopy Code
let promise = new Promise(function(resolve, reject) {
  // 异步操作代码

  let success = true;  // 模拟异步操作结果
  if (success) {
    resolve("操作成功!");  // 操作成功时调用 resolve
  } else {
    reject("操作失败!");  // 操作失败时调用 reject
  }
});

Promise 的基本用法

你可以通过 .then().catch() 来处理 Promise 的结果或错误:

  1. .then(onFulfilled, onRejected) :在 Promise 完成时调用 onFulfilled,如果失败则调用 onRejected
  2. .catch(onRejected) :用于捕获 Promise 的错误。
javascriptCopy Code
// 示例:一个简单的 Promise
let myPromise = new Promise((resolve, reject) => {
  let success = true;

  if (success) {
    resolve("操作成功!");
  } else {
    reject("操作失败!");
  }
});

myPromise
  .then((result) => {
    console.log(result);  // 操作成功时执行
  })
  .catch((error) => {
    console.error(error);  // 操作失败时执行
  });

示例:用 Promise 封装异步操作

假设你要进行一个异步操作,例如模拟读取文件内容。你可以用 Promise 来封装这个操作,处理成功或失败的情况。

javascriptCopy Code
function readFile(filePath) {
  return new Promise((resolve, reject) => {
    // 模拟读取文件的操作
    setTimeout(() => {
      if (filePath === "validFile.txt") {
        resolve("文件内容:Hello World!");
      } else {
        reject("文件不存在!");
      }
    }, 1000);  // 模拟异步操作延迟
  });
}

readFile("validFile.txt")
  .then((data) => {
    console.log("文件读取成功:", data);
  })
  .catch((error) => {
    console.error("文件读取失败:", error);
  });

Promise 链式调用

Promise 支持链式调用,也就是说你可以通过连续的 .then() 方法来处理多个异步操作。

javascriptCopy Code
let promise = new Promise((resolve, reject) => {
  resolve(10);
});

promise
  .then((result) => {
    console.log(result); // 输出: 10
    return result * 2;
  })
  .then((result) => {
    console.log(result); // 输出: 20
    return result * 3;
  })
  .then((result) => {
    console.log(result); // 输出: 60
  });

Promise.all()

Promise.all() 方法接受一个包含多个 Promise 实例的数组,并返回一个新的 Promise,该 Promise 在所有输入的 Promise 都完成时才会完成。如果其中任何一个 Promise 被拒绝,Promise.all() 将立即失败。

javascriptCopy Code
let promise1 = new Promise((resolve) => setTimeout(resolve, 1000, "结果1"));
let promise2 = new Promise((resolve) => setTimeout(resolve, 2000, "结果2"));
let promise3 = new Promise((resolve) => setTimeout(resolve, 3000, "结果3"));

Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results);  // 输出: ["结果1", "结果2", "结果3"]
  })
  .catch((error) => {
    console.error(error);  // 如果任何一个 Promise 被拒绝,这里会捕获到
  });

Promise.race()

Promise.race() 方法也接受一个包含多个 Promise 实例的数组,但是它返回一个新的 Promise,并且会以第一个完成的 Promise 的结果(无论是成功还是失败)为结果。

javascriptCopy Code
let promise1 = new Promise((resolve) => setTimeout(resolve, 3000, "结果1"));
let promise2 = new Promise((resolve) => setTimeout(resolve, 2000, "结果2"));
let promise3 = new Promise((resolve) => setTimeout(resolve, 1000, "结果3"));

Promise.race([promise1, promise2, promise3])
  .then((result) => {
    console.log(result);  // 输出: "结果3"(因为它是第一个完成的)
  })
  .catch((error) => {
    console.error(error);
  });

Promise.allSettled()

Promise.allSettled() 方法接受一个 Promise 数组,返回一个新的 Promise,这个 Promise 会在所有的 Promise 完成后(无论是成功还是失败)返回一个数组,其中每个元素表示对应 Promise 的状态和结果。

javascriptCopy Code
let promise1 = Promise.resolve("成功");
let promise2 = Promise.reject("失败");

Promise.allSettled([promise1, promise2])
  .then((results) => {
    console.log(results);
    // 输出:
    // [
    //   { status: 'fulfilled', value: '成功' },
    //   { status: 'rejected', reason: '失败' }
    // ]
  });

async / await

asyncawait 是基于 Promise 的语法糖,简化了异步操作的写法。async 用于声明一个异步函数,await 用于等待一个 `Promise [Something went wrong, please try again later.]