JavaScript 的 Promise 用法详解及使用场景

JavaScript 的 Promise 用法详解及使用场景

Promise 是 JavaScript 中用于管理异步操作的对象,可以让代码更加简洁、可读,并且避免“回调地狱”。以下是 Promise 的详细用法及其适用场景。


一、Promise 的核心概念

  1. 状态(State)
    pending:初始状态,表示操作未完成。
    fulfilled:操作成功完成。
    rejected:操作失败。
  2. 状态特点
    状态一旦从 pending 转为 fulfilled 或 rejected,便不可再更改。
    一个 Promise 只能有一个最终状态(成功或失败)。
  3. 构造函数
    创建 Promise 的语法:
    const promise = new Promise((resolve, reject) => {
      // 异步操作
      if (操作成功) {
        resolve(成功值);
      } else {
        reject(失败原因);
      }
    });
    

二、Promise 的用法详解

  1. 基本用法

    const promise = new Promise((resolve, reject) => {
      let isSuccess = true;
      if (isSuccess) {
        resolve("操作成功");
      } else {
        reject("操作失败");
      }
    });
    
    promise
      .then((result) => {
        console.log(result);  // 操作成功
      })
      .catch((error) => {
        console.error(error);  // 操作失败
      });
    
  2. 链式调用
    • then() 方法会返回一个新的 Promise,因此可以链式调用来处理多个异步操作。

    new Promise((resolve) => resolve(2))
      .then((value) => {
        console.log(value);  // 输出 2
        return value * 2;
      })
      .then((value) => {
        console.log(value);  // 输出 4
        return value * 3;
      })
      .then((value) => {
        console.log(value);  // 输出 12
      });
    
  3. 错误处理
    • 使用 catch() 捕获 Promise 中的错误。

    new Promise((resolve, reject) => {
      reject("发生错误");
    })
      .then((value) => {
        console.log(value);  // 不会执行
      })
      .catch((error) => {
        console.error(error);  // 发生错误
      });
    

    • 错误会沿着链条传递,直到被 catch 捕获。

    new Promise((resolve, reject) => {
      reject("错误1");
    })
      .then(() => {
        console.log("成功1");
      })
      .then(() => {
        console.log("成功2");
      })
      .catch((error) => {
        console.error(error);  // 捕获 "错误1"
      });
    
  4. finally() 方法
    • finally() 方法会在 Promise 结束后(无论是成功还是失败)执行操作。

    new Promise((resolve) => resolve("操作完成"))
      .then((result) => {
        console.log(result);  // 操作完成
      })
      .finally(() => {
        console.log("结束操作");  // 始终执行
      });
    

三、Promise 的静态方法

  1. Promise.resolve()
    • 创建一个已成功的 Promise。

    Promise.resolve("快速成功").then((value) => console.log(value));  // 快速成功
    
  2. Promise.reject()
    • 创建一个已失败的 Promise。

    Promise.reject("快速失败").catch((error) => console.error(error));  // 快速失败
    
  3. Promise.all()
    • 等待所有 Promise 完成,返回包含结果的数组;若有一个失败,则整个返回失败。

    const p1 = Promise.resolve(1);
    const p2 = Promise.resolve(2);
    const p3 = Promise.reject("失败");
    
    Promise.all([p1, p2])
      .then((results) => console.log(results))  // [1, 2]
      .catch((error) => console.error(error));  // 不会执行
    
    Promise.all([p1, p2, p3])
      .then((results) => console.log(results))  // 不会执行
      .catch((error) => console.error(error));  // 失败
    
  4. Promise.allSettled()
    • 等待所有 Promise 完成,无论成功或失败,返回每个 Promise 的结果。

    Promise.allSettled([
      Promise.resolve("成功"),
      Promise.reject("失败"),
    ]).then((results) => console.log(results));
    /* 输出:
    [
      { status: "fulfilled", value: "成功" },
      { status: "rejected", reason: "失败" }
    ]
    */
    
  5. Promise.race()
    • 返回第一个完成的 Promise(无论成功还是失败)。

    const p1 = new Promise((resolve) => setTimeout(() => resolve("慢"), 100));
    const p2 = new Promise((resolve) => setTimeout(() => resolve("快"), 50));
    
    Promise.race([p1, p2]).then((value) => console.log(value));  // 快
    
  6. Promise.any()
    • 返回第一个成功的 Promise;如果所有 Promise 都失败,则返回 AggregateError。

    Promise.any([
      Promise.reject("失败1"),
      Promise.reject("失败2"),
      Promise.resolve("成功"),
    ]).then((value) => console.log(value));  // 成功
    
    Promise.any([
      Promise.reject("失败1"),
      Promise.reject("失败2"),
    ]).catch((error) => console.error(error.errors));  // ["失败1", "失败2"]
    

四、Promise 的使用场景

  1. 异步请求
    • 使用 Promise 处理 HTTP 请求,链式调用后处理数据。

    fetch("https://jsonplaceholder.typicode.com/posts/1")
      .then((response) => response.json())
      .then((data) => console.log(data))
      .catch((error) => console.error("请求失败", error));
    
  2. 多个异步操作并发处理
    • 使用 Promise.all() 同时执行多个请求。

    const fetch1 = fetch("https://jsonplaceholder.typicode.com/posts/1");
    const fetch2 = fetch("https://jsonplaceholder.typicode.com/posts/2");
    
    Promise.all([fetch1, fetch2])
      .then((responses) => Promise.all(responses.map((res) => res.json())))
      .then((data) => console.log(data))
      .catch((error) => console.error(error));
    
  3. 异步任务的错误恢复
    • 使用 catch 捕获错误并进行恢复操作。

    fetch("https://jsonplaceholder.typicode.com/posts/1")
      .then((response) => {
        if (!response.ok) {
          throw new Error("网络错误");
        }
        return response.json();
      })
      .catch((error) => {
        console.error("捕获错误:", error);
        return { error: "默认值" };
      })
      .then((data) => console.log(data));
    
  4. 动画控制
    • 配合 setTimeout 或动画框架(如 GSAP)实现动画序列。

    function delay(ms) {
      return new Promise((resolve) => setTimeout(resolve, ms));
    }
    
    delay(1000)
      .then(() => {
        console.log("1秒后执行");
        return delay(2000);
      })
      .then(() => {
        console.log("再过2秒执行");
      });
    

五、总结

  1. Promise 的优点:
    o 更优雅的异步编程方式。
    o 避免回调地狱,代码更加易读。
    o 提供了丰富的静态方法处理复杂异步操作。
  2. 适用场景:
    o 异步请求和数据处理。
    o 并发任务管理。
    o 动画与计时操作。
    o 错误处理和恢复。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

落雪寒窗-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值