http 请求-04-promise 对象 + async/await 入门介绍

http 请求系列

http request-01-XMLHttpRequest XHR 简单介绍

http request-01-XMLHttpRequest XHR 标准

Ajax 详解-01-AJAX(Asynchronous JavaScript and XML)入门介绍

Ajax XHR 的替代方案-fetch

Ajax XHR 的替代方案-fetch 标准

Ajax 的替代方案-axios.js

http 请求-04-promise 对象 + async/await

Promise 是什么?

Promise 是 JavaScript 中用于异步编程的一种对象。它代表了一个可能现在还没有结果,但将来会有结果的值。

Promise 的主要目的是提供一个更合理、更可控的方式来处理异步操作,比如网络请求、文件读写等。

以下是 Promise 的一些关键点:

  1. 状态:Promise 有三种状态:

    • Pending(等待):初始状态,既不是成功,也不是失败状态。
    • Fulfilled(已成功):意味着操作成功完成。
    • Rejected(已失败):意味着操作失败。
  2. 创建 :使用 new Promise 构造函数创建一个新的 Promise 对象。构造函数接受一个执行器函数(executor function),它将在 Promise 创建后立即执行。

    javascript 复制代码
    const myPromise = new Promise((resolve, reject) => {
      // 异步操作
    });
  3. 执行器函数 :这是一个自动执行的函数,接受两个参数 resolvereject

    • resolve:当异步操作成功时调用,将 Promise 状态转变为 Fulfilled。
    • reject:当异步操作失败时调用,将 Promise 状态转变为 Rejected。
  4. 链式调用 :Promise 可以通过 .then().catch() 方法进行链式调用。.then() 用于指定当 Promise 成功时的回调函数,而 .catch() 用于指定当 Promise 失败时的回调函数。

    javascript 复制代码
    myPromise
      .then((result) => {
        // 处理结果
      })
      .catch((error) => {
        // 处理错误
      });
  5. 错误处理 :如果 Promise 被拒绝,错误会传递到最近的 .catch() 调用。如果在 Promise 链中没有 .catch(),错误将被忽略。

  6. Promise.all():这是一个静态方法,接受一组 Promise 对象作为输入,并返回一个新的 Promise 对象。这个新的 Promise 在所有输入的 Promise 都成功完成时才会成功,如果任何一个输入的 Promise 失败,则立即失败。

  7. Promise.race():这也是一个静态方法,同样接受一组 Promise 对象。它返回一个新的 Promise,这个 Promise 将在输入的 Promise 中任何一个首先解决或拒绝时解决或拒绝。

  8. finally() :无论 Promise 是解决还是拒绝,.finally() 方法都会被调用。它通常用于执行一些清理工作。

  9. Async/Await :基于 Promise 的 asyncawait 关键字提供了一种更简洁和直观的方式来编写异步代码,使得异步代码看起来和同步代码类似。

    javascript 复制代码
    async function asyncFunction() {
      try {
        const result = await myPromise; // 等待 Promise 解决
        console.log(result);
      } catch (error) {
        console.error(error);
      }
    }

Promise 是 JavaScript 异步编程的核心,它们使得处理异步操作变得更加简单和可靠。

为什么需要 Promise ?解决了什么问题

Promise 出现之前,JavaScript 中处理异步操作主要依赖回调函数(Callback)。

然而,回调函数存在一些问题,这些问题被称为 "回调地狱"(Callback Hell)或 "回调嵌套",Promise 就是为了解决这些问题而设计的。以下是 Promise 解决的主要问题:

  1. 回调地狱:当多个异步操作需要按顺序执行时,嵌套的回调函数会导致代码难以阅读和维护。

    javascript 复制代码
    getData(function(a) {
      getMoreData(a, function(b) {
        getEvenMoreData(b, function(c) {
          // ...
        });
      });
    });

    Promise 允许你以链式的方式书写异步操作,使代码更加清晰:

    javascript 复制代码
    getData()
      .then(a => getMoreData(a))
      .then(b => getEvenMoreData(b))
      .then(c => {
        // 处理结果
      });
  2. 错误处理 :在回调函数中,错误处理通常需要在每个回调中单独处理。Promise 的 .catch() 方法提供了统一的错误处理机制。

    javascript 复制代码
    // 使用回调时的错误处理
    getData(function(err, data) {
      if (err) {
        // 错误处理
      } else {
        // 处理数据
      }
    });
    
    // 使用 Promise 的错误处理
    getData()
      .then(data => {
        // 处理数据
      })
      .catch(err => {
        // 统一错误处理
      });
  3. 代码组织:Promise 提供了一种更好的方式组织异步代码,使得逻辑更加清晰,也更容易复用。

  4. 状态管理:Promise 明确了异步操作的三种状态(Pending、Fulfilled、Rejected),这使得状态管理更加明确和容易。

  5. 并发执行 :Promise 的 Promise.all() 方法可以轻松处理多个并发的异步操作,并在所有操作都完成后执行特定的回调。

  6. 顺序执行:Promise 允许你按顺序执行异步操作,而不需要在每个步骤中手动传递回调函数。

  7. 更好的控制流程 :使用 asyncawait,你可以以一种更接近同步代码的方式来编写异步逻辑,这使得代码更加直观和易于理解。

  8. 避免阻塞:在某些情况下,回调函数可能会导致程序阻塞,尤其是在错误处理不当的情况下。Promise 提供了一种更流畅的方式来避免这种情况。

总的来说,Promise 提供了一种更加强大、灵活和可读性更强的方式来处理 JavaScript 中的异步操作,极大地改善了开发体验。

Promise 与 async/await 有什么不同,它们在实际开发中应该如何选择使用?

Promise 和 async/await 都是处理 JavaScript 中异步操作的方式,但它们之间存在一些关键的区别。以下是它们的主要不同点以及在实际开发中的使用选择建议:

Promise

  • 定义:Promise 是一种对象,代表了一个异步操作的最终完成或失败。
  • 语法 :使用 .then().catch() 方法来指定操作成功或失败时的回调函数。
  • 链式调用 :可以进行链式调用,但深层嵌套的 .then() 可能导致所谓的 "回调地狱"。
  • 错误处理:需要在每个 Promise 链中明确处理错误,否则未捕获的错误可能会被忽略。

async/await

  • 定义asyncawait 是建立在 Promise 之上的语法糖,使得异步代码看起来和写起来更像同步代码。
  • 语法async 关键字用于声明一个函数或块是异步的,await 关键字用于等待一个 Promise 解决。
  • 可读性:使得异步代码更易于阅读和理解,因为它减少了回调和 Promise 链的复杂性。
  • 错误处理 :可以使用传统的 try/catch 语句来处理错误,这使得错误处理更直观和一致。

在实际开发中的选择使用

  1. 可读性和简洁性

    • 如果你倾向于写更简洁、更易读的代码,推荐使用 async/await。它让异步代码的流程看起来更直观。
  2. 错误处理

    • 如果你需要更直观的错误处理方式,推荐使用 async/await ,因为它允许使用 try/catch 块。
  3. 代码复杂性

    • 对于复杂的异步逻辑,特别是涉及多个并行或依赖的异步操作,使用 Promise 可能更灵活,尤其是结合 Promise.all()Promise.race() 等方法。
  4. 库和框架的兼容性

    • 如果你正在使用的库或框架主要返回 Promise,可能需要使用 Promise 来与它们交互,尽管 async/await 也可以与 Promise 一起使用。
  5. 团队习惯和代码风格

    • 考虑团队的熟悉度和代码风格。如果团队更熟悉 Promise,或者项目中已经广泛使用了 Promise,那么继续使用 Promise 可能是更好的选择。
  6. 逐步迁移

    • 如果你正在维护一个已经使用 Promise 的大型项目,可能需要逐步迁移到 async/await,以保持代码的一致性。
  7. 环境支持

    • 虽然现代浏览器和 Node.js 都支持 async/await,但如果你的目标环境需要支持较旧的 JavaScript 引擎,可能需要考虑 Promise 的兼容性。
相关推荐
wkj0019 分钟前
接口实现类向上转型和向上转型解析
java·开发语言·c#
qqxhb10 分钟前
零基础设计模式——行为型模式 - 观察者模式
java·观察者模式·设计模式·go
寒士obj37 分钟前
类加载的过程
java·开发语言
无名之逆40 分钟前
大三自学笔记:探索Hyperlane框架的心路历程
java·开发语言·前端·spring boot·后端·rust·编程
Chuck1sn42 分钟前
我把 Cursor AI 整合到 Ruoyi 中,从此让 Java 脚手架脱离人工!
java·vue.js·后端
水木石画室1 小时前
Spring Boot 常用注解面试题深度解析
java·spring boot·后端
hweiyu001 小时前
tomcat指定使用的jdk版本
java·开发语言·tomcat
百锦再1 小时前
.NET 类库开发详细指南c
java·log4j·.net·net·dot
黎䪽圓2 小时前
【Java多线程从青铜到王者】阻塞队列(十)
java·开发语言