Promise 让你的代码更优雅、更高效!

Promise 让你的代码更优雅、更高效!_第1张图片

目录

    • 一、 什么是 Promise?
    • 二、 Promise 的基本用法
    • 三、 Promise 的状态转换
    • 四、 Promise 的链式调用
    • 五、 Promise 的静态方法
    • 六、 async/await (Promise 的语法糖)
    • 总结

我的其他文章也讲解的比较有趣,如果喜欢博主的讲解方式,可以多多支持一下,感谢!
了解双亲委派机制请看: 双亲委派机制,你真的懂吗?

其他优质专栏: 【SpringBoot】【多线程】【Redis】【✨设计模式专栏(已完结)】…等

如果喜欢作者的讲解方式,可以点赞收藏加关注,你的支持就是我的动力
✨更多文章请看个人主页: 码熔burning

这篇文章来讲讲前端的知识Promise !

一、 什么是 Promise?

想象一下,你去餐厅点了一份外卖。你点了之后,餐厅会给你一个“承诺”:他们会给你送餐。

  • Promise 就好比这个“承诺”。
  • 这个承诺有三种状态:
    • Pending(等待中): 餐厅正在做你的外卖,还没送到。 ⏳
    • Fulfilled(已成功): 餐厅已经把外卖送到你手里了,你吃上了!
    • Rejected(已失败): 餐厅告诉你,今天外卖小哥不够,送不了了!

Promise 的本质: Promise 是一个代表异步操作最终完成(或失败)的对象。 它允许你以一种更清晰、更可控的方式处理异步操作,避免回调地狱。 ‍♀️➡️

二、 Promise 的基本用法

// 创建一个 Promise
const myPromise = new Promise((resolve, reject) => {
  // 这里写异步操作,比如发送一个网络请求,或者延迟一段时间

  setTimeout(() => {
    const success = true; // 假设操作成功

    if (success) {
      // 调用 resolve 表示操作成功
      resolve("操作成功!"); // resolve 里面可以放成功的结果数据
    } else {
      // 调用 reject 表示操作失败
      reject("操作失败!"); // reject 里面可以放失败的原因
    }
  }, 2000); // 延迟 2 秒
});

// 使用 Promise
myPromise
  .then((result) => {
    // 如果 Promise 成功了,会执行这里的代码
    console.log("成功:", result);
  })
  .catch((error) => {
    // 如果 Promise 失败了,会执行这里的代码
    console.error("失败:", error);
  })
  .finally(() => {
    // 无论 Promise 成功还是失败,都会执行这里的代码
    console.log("操作完成!✅");
  });

console.log("Promise 创建后立即执行的代码 ");

输出结果:

Promise 创建后立即执行的代码 
// 2 秒后
成功: 操作成功!
操作完成!✅

代码解释:

  • new Promise((resolve, reject) => { ... }) 创建一个新的 Promise 对象。
    • resolvereject 是两个函数,它们由 JavaScript 引擎提供。
    • resolve(value): 调用 resolve 表示 Promise 操作成功,value 是成功的结果。
    • reject(reason): 调用 reject 表示 Promise 操作失败,reason 是失败的原因。
  • setTimeout(() => { ... }, 2000) 模拟一个异步操作,这里是延迟 2 秒。
  • .then((result) => { ... }) then 方法用于处理 Promise 成功的情况。
    • result: 是 resolve 函数传递过来的成功结果。
  • .catch((error) => { ... }) catch 方法用于处理 Promise 失败的情况。
    • error: 是 reject 函数传递过来的失败原因。
  • .finally(() => { ... }) finally 方法用于处理 Promise 无论成功还是失败都需要执行的代码。
  • 执行顺序:
    1. new Promise 创建 Promise 对象,并立即执行 Promise 构造函数中的代码。
    2. console.log("Promise 创建后立即执行的代码"); 会立即执行,因为 Promise 内部的异步操作是延迟执行的。
    3. 2 秒后,setTimeout 中的代码执行,根据 success 的值调用 resolvereject
    4. 如果 resolve 被调用,.then 中的代码会被执行。
    5. 如果 reject 被调用,.catch 中的代码会被执行。
    6. 无论 resolve 还是 reject 被调用,.finally 中的代码都会被执行。

三、 Promise 的状态转换

Promise 的状态只能从 Pending 转换为 FulfilledRejected,而且一旦转换,就不能再变回 Pending 状态。

  • Pending -> Fulfilled: 通过调用 resolve() 函数。 ✅
  • Pending -> Rejected: 通过调用 reject() 函数。 ❌
    Promise 让你的代码更优雅、更高效!_第2张图片

四、 Promise 的链式调用

Promise 最强大的特性之一就是可以进行链式调用,这使得处理多个异步操作变得非常方便。

function fetchData(url) {
  return new Promise((resolve, reject) => {
    fetch(url)
      .then(response => {
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        return response.json();
      })
      .then(data => resolve(data))
      .catch(error => reject(error));
  });
}

fetchData('https://jsonplaceholder.typicode.com/todos/1')
  .then(data => {
    console.log('Data received:', data);
    return data.title; // 返回一个值,传递给下一个 then
  })
  .then(title => {
    console.log('Title:', title);
    return `The title is: ${title} `; // 返回一个值,传递给下一个 then
  })
  .then(formattedTitle => {
    console.log('Formatted title:', formattedTitle);
  })
  .catch(error => {
    console.error('Error fetching data:', error);
  });

输出结果:

Data received: { userId: 1, id: 1, title: 'delectus aut autem', completed: false }
Title: delectus aut autem
Formatted title: The title is: The title is: delectus aut autem 

链式调用的好处:

  • 代码更清晰: 避免了回调地狱,使代码更易于阅读和维护。
  • 错误处理更集中: 可以在链的末尾使用一个 catch 捕获所有错误。
  • 数据传递更方便: 每个 then 可以将处理后的数据传递给下一个 then。 ➡️

五、 Promise 的静态方法

Promise 提供了一些静态方法,用于处理多个 Promise。 ‍‍‍

  • Promise.all(promises) 接收一个 Promise 数组,当所有 Promise 都成功时,返回一个包含所有结果的 Promise。 如果其中任何一个 Promise 失败,则立即返回一个 rejected 的 Promise。

    const promise1 = Promise.resolve(1);
    const promise2 = new Promise((resolve, reject) => setTimeout(resolve, 200, 'foo'));
    const promise3 = new Promise((resolve, reject) => setTimeout(resolve, 100, 'bar'));
    
    Promise.all([promise1, promise2, promise3])
      .then((values) => {
        console.log(values); // 输出: [1, "foo", "bar"]
      });
    
  • Promise.race(promises) 接收一个 Promise 数组,返回第一个 resolve 或 reject 的 Promise。 ‍♀️

    const promise1 = new Promise((resolve, reject) => {
      setTimeout(resolve, 500, 'one');
    });
    
    const promise2 = new Promise((resolve, reject) => {
      setTimeout(resolve, 100, 'two');
    });
    
    Promise.race([promise1, promise2])
      .then((value) => {
        console.log(value); // 输出: "two" (promise2 更快 resolve)
      });
    
  • Promise.resolve(value) 返回一个 resolved 的 Promise,其值为 value。 ✅

    const resolvedPromise = Promise.resolve(42);
    
    resolvedPromise.then((value) => {
      console.log(value); // 输出: 42
    });
    
  • Promise.reject(reason) 返回一个 rejected 的 Promise,其原因为 reason。 ❌

    const rejectedPromise = Promise.reject('Something went wrong!');
    
    rejectedPromise.catch((reason) => {
      console.error(reason); // 输出: "Something went wrong!"
    });
    

六、 async/await (Promise 的语法糖)

async/await 是 ES2017 引入的语法糖,它使异步代码看起来更像同步代码,更容易阅读和编写。 async/await 实际上是基于 Promise 实现的。

async function fetchDataAndProcess(url) {
  try {
    const response = await fetch(url); // await 等待 Promise 完成
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`);
    }
    const data = await response.json(); // await 等待 Promise 完成
    console.log('Data received:', data);
    return data.title;
  } catch (error) {
    console.error('Error fetching data:', error);
    throw error; // 重新抛出错误,让调用者处理
  }
}

async function main() {
  try {
    const title = await fetchDataAndProcess('https://jsonplaceholder.typicode.com/todos/1');
    console.log('Title:', title);
  } catch (error) {
    console.error('Main function caught an error:', error);
  }
}

main();

输出结果:

Data received: { userId: 1, id: 1, title: 'delectus aut autem', completed: false }
Title: delectus aut autem

代码解释:

  • async function async 关键字用于声明一个异步函数。 异步函数内部可以使用 await 关键字。
  • await await 关键字用于等待一个 Promise 完成。 它只能在 async 函数内部使用。
    • await fetch(url): 等待 fetch 函数返回的 Promise 完成,并将结果赋值给 response
    • await response.json(): 等待 response.json() 返回的 Promise 完成,并将结果赋值给 data
  • try...catch try...catch 块用于捕获异步函数中发生的错误。

async/await 的好处:

  • 代码更简洁: 避免了大量的 .then.catch,使代码更易于阅读和理解。
  • 代码更像同步代码: 使异步代码的逻辑更清晰,更容易维护。 ✍️
  • 错误处理更方便: 可以使用 try...catch 块集中处理错误。 ️

总结

  • Promise 是一个代表异步操作最终完成(或失败)的对象。
  • Promise 有三种状态:PendingFulfilledRejected
  • 可以使用 .then 处理成功的情况,使用 .catch 处理失败的情况,使用 .finally 处理无论成功还是失败都需要执行的代码。 ✅❌
  • Promise 可以进行链式调用,方便处理多个异步操作。
  • Promise 提供了一些静态方法,用于处理多个 Promise。 ‍‍‍
  • async/await 是 Promise 的语法糖,使异步代码看起来更像同步代码。

希望这篇文章能够帮助你彻底理解 Promise! 多写代码,多练习,你就能成为 Promise 大师! ‍♂️

你可能感兴趣的:(前端,前端,Promise)