ES6 中的 Promise 和 async/await 异步编程详解

异步编程简介

在前端开发中,我们经常需要处理异步操作,例如发送 AJAX 请求、读取本地存储、执行定时任务等等。异步操作与同步操作的不同点在于,异步操作需要在后台执行,并且不会阻塞主线程,使得程序可以同时执行多个任务,提高了程序的性能。

然而,异步编程也带来了一些挑战。异步操作的结果不是立即可用的,需要等待异步操作完成后才能继续执行下一步操作。在传统的回调函数中,这种异步操作的嵌套会导致代码难以维护和理解。因此,ES6 中引入了 Promise 和 async/await 异步编程模式,使异步编程更加简洁、易读和易维护。

Promise

Promise 是 ES6 中引入的一种异步编程模式。它通过链式调用的方式,解决了回调函数嵌套的问题,使得异步代码更加清晰易读。

Promise 的基本使用

Promise 有三种状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。当一个 Promise 被创建时,它处于 pending 状态。当 Promise 成功完成时,它会进入 fulfilled 状态,并将结果传递给 then() 方法;当 Promise 失败时,它会进入 rejected 状态,并将错误传递给 catch() 方法。

下面是一个简单的 Promise 示例,模拟了一个异步操作:

----- ------- - --- ----------------- ------- -- -
  ------------- -- -
    ----- ------ - --------------
    -- ------- - ---- -
      ----------------
    - ---- -
      ---------- -----------------
    -
  -- ------
---

--------------------- -- -
  ----------------------- ------------
---------------- -- -
  ---------------------- -----------
---

在这个示例中,我们创建了一个 Promise,模拟了一个 1 秒钟后返回随机数的异步操作。如果随机数大于 0.5,则 Promise 进入 fulfilled 状态,并将随机数传递给 then() 方法;否则,Promise 进入 rejected 状态,并将错误传递给 catch() 方法。

Promise 的进阶使用

除了基本的 Promise 使用方式外,ES6 还提供了一些高级的 Promise 方法,例如 Promise.all() 和 Promise.race()。

Promise.all()

Promise.all() 方法接收一个 Promise 数组作为参数,返回一个新的 Promise,当所有的 Promise 都成功完成时,它才会进入 fulfilled 状态;当任意一个 Promise 失败时,它就会进入 rejected 状态。如果 Promise 数组中有一个或多个 Promise 失败,Promise.all() 方法返回的 Promise 就会立即进入 rejected 状态,并将第一个失败的 Promise 的错误传递给 catch() 方法。

下面是一个使用 Promise.all() 的示例,模拟了同时发送多个 AJAX 请求的情况:

----- ---- - ---------------------------------------- --------------------------------------- ----------------------------------------

----- -------- - -------------- -- -
  ------ -------------------------- -- -----------------
---

------------------------------------ -- -
  ---------------------
---------------- -- -
  ---------------------
---

在这个示例中,我们定义了一个包含三个 URL 的数组,然后使用 fetch() 方法发送 AJAX 请求,并将结果解析为 JSON 格式。使用 Promise.all() 方法,我们可以同时发送这三个请求,并在所有请求都成功完成后,打印出结果数组。

Promise.race()

Promise.race() 方法和 Promise.all() 方法类似,也接收一个 Promise 数组作为参数,返回一个新的 Promise。不同的是,Promise.race() 方法只要有一个 Promise 成功完成或失败,它就会进入对应的状态,并将结果或错误传递给 then() 或 catch() 方法。

下面是一个使用 Promise.race() 的示例,模拟了一个超时请求的情况:

----- ------- - --- ----------------- ------- -- -
  ------------- -- -
    ---------- ------------------
  -- ------
---

----- ------- - --- ----------------- ------- -- -
  ------------- -- -
    ---------- -------------- -- ------ --- --------
  -- ------
---

---------------------- ----------------------- -- -
  --------------------
---------------- -- -
  ---------------------
---

在这个示例中,我们创建了一个 Promise,模拟了一个 5 秒钟后返回结果的异步操作。同时,我们还创建了一个超时 Promise,模拟了一个 3 秒钟后请求超时的情况。使用 Promise.race() 方法,我们可以同时执行这两个 Promise,并在其中一个 Promise 成功完成或失败后,打印出结果或错误信息。

async/await

async/await 是 ES8 中引入的一种异步编程模式。它基于 Promise,使用 async 和 await 关键字,使异步代码更加简洁、易读和易维护。

async/await 的基本使用

async/await 基于 Promise,可以将 Promise 的链式调用转换为类似同步代码的形式。在 async 函数中,我们可以使用 await 关键字等待 Promise 完成,并将结果赋值给变量,这样我们就可以像处理同步代码一样处理异步代码了。

下面是一个简单的 async/await 示例,模拟了一个异步操作:

----- -------- --------- -
  ----- ------- - --- ----------------- ------- -- -
    ------------- -- -
      ----- ------ - --------------
      -- ------- - ---- -
        ----------------
      - ---- -
        ---------- -----------------
      -
    -- ------
  ---

  --- -
    ----- ------ - ----- --------
    ----------------------- ------------
  - ----- ------- -
    ---------------------- -----------
  -
-

----------

在这个示例中,我们定义了一个 async 函数 getData(),在其中创建了一个 Promise,模拟了一个 1 秒钟后返回随机数的异步操作。使用 await 关键字,我们可以等待 Promise 完成,并将结果赋值给变量 result。如果 Promise 成功完成,则打印出成功的信息;否则,打印出失败的信息。

async/await 的进阶使用

除了基本的 async/await 使用方式外,ES8 还提供了一些高级的 async/await 方法,例如 Promise.all() 和 Promise.race()。

Promise.all()

在 async/await 中使用 Promise.all() 方法,可以等待多个 Promise 完成,并将结果作为一个数组返回。与 Promise.all() 方法类似,当其中一个 Promise 失败时,整个 async 函数就会进入 rejected 状态,并将第一个失败的 Promise 的错误传递给 catch() 方法。

下面是一个使用 Promise.all() 的示例,模拟了同时发送多个 AJAX 请求的情况:

----- -------- --------- -
  ----- ---- - ---------------------------------------- --------------------------------------- ----------------------------------------

  ----- -------- - -------------- -- -
    ------ -------------------------- -- -----------------
  ---

  --- -
    ----- ------- - ----- ----------------------
    ---------------------
  - ----- ------- -
    ---------------------
  -
-

----------

在这个示例中,我们定义了一个 async 函数 getData(),在其中定义了一个包含三个 URL 的数组。使用 fetch() 方法发送 AJAX 请求,并将结果解析为 JSON 格式。使用 Promise.all() 方法,我们可以等待这三个请求都完成,并将结果作为一个数组返回。

Promise.race()

在 async/await 中使用 Promise.race() 方法,可以等待多个 Promise 中的第一个完成,并将结果或错误信息作为返回值。与 Promise.race() 方法类似,当其中一个 Promise 失败时,整个 async 函数就会进入 rejected 状态,并将第一个失败的 Promise 的错误传递给 catch() 方法。

下面是一个使用 Promise.race() 的示例,模拟了一个超时请求的情况:

----- -------- --------- -
  ----- ------- - --- ----------------- ------- -- -
    ------------- -- -
      ---------- ------------------
    -- ------
  ---

  ----- ------- - --- ----------------- ------- -- -
    ------------- -- -
      ---------- -------------- -- ------ --- --------
    -- ------
  ---

  --- -
    ----- ------ - ----- ---------------------- ----------
    --------------------
  - ----- ------- -
    ---------------------
  -
-

----------

在这个示例中,我们定义了一个 async 函数 getData(),在其中创建了一个 Promise,模拟了一个 5 秒钟后返回结果的异步操作。同时,我们还创建了一个超时 Promise,模拟了一个 3 秒钟后请求超时的情况。使用 Promise.race() 方法,我们可以等待这两个 Promise 中的第一个完成,并将结果或错误信息作为返回值。

总结

在本文中,我们介绍了 ES6 中的 Promise 和 ES8 中的 async/await 两种异步编程模式。它们都可以使异步代码更加简洁、易读和易维护。Promise 通过链式调用的方式解决了回调函数嵌套的问题,使得异步代码更加清晰易读;async/await 基于 Promise,使用 async 和 await 关键字,使异步代码更加类似同步代码的形式,使得异步代码更加易于编写和理解。

在实际开发中,我们可以根据具体情况选择使用 Promise 或 async/await。当需要等待多个异步操作完成时,可以使用 Promise.all() 或 async/await;当需要等待多个异步操作中的第一个完成时,可以使用 Promise.race() 或 async/await。无论是哪种方式,都可以使我们的异步代码更加清晰、易读和易维护。

来源:JavaScript中文网 ,转载请联系管理员! 本文地址:https://www.javascriptcn.com/post/655d797cd2f5e1655d7bf9e2


猜你喜欢

  • Next.js 服务端渲染如何通信?

    Next.js 是一种基于 React 的轻量级框架,它提供了一种简单的方法来实现服务端渲染 (SSR)。SSR 有很多好处,例如更好的 SEO,更快的首次渲染时间,更好的用户体验等。

    1 年前
  • 如何在 ES11 中使用 Promise.allSettled 方法处理 Promise 数组

    在前端开发中,我们经常需要处理 Promise 数组,以便在所有 Promise 都完成后执行某些操作。ES6 中引入了 Promise.all 方法来实现这个功能,但它只有在所有 Promise 都...

    1 年前
  • Fastify 中如何实现缓存控制

    在网站开发中,缓存是提高网站性能的重要手段之一。在 Fastify 中,我们可以使用一些插件和代码来实现缓存控制,从而提高网站的性能和响应速度。 什么是缓存控制 缓存控制是指在客户端和服务器之间设置缓...

    1 年前
  • ESLint:在 React Native 项目中解决 prop-types 错误

    在 React Native 项目中,我们经常会使用 prop-types 库来验证组件的属性类型,以确保代码的健壮性和可维护性。然而,有时候我们会遇到一些 prop-types 的错误,如 Inva...

    1 年前
  • 构建使用了大量 SVG Icon 的 Vue 项目

    在前端开发中,图标是一个不可或缺的元素,而使用 SVG Icon 则是一个非常流行的选择。SVG Icon 具有矢量图形的优点,能够自适应不同分辨率的屏幕,并且支持无限缩放而不会失真。

    1 年前
  • PWA 服务器端实现的方法以及 Web Push 的应用

    前言 在移动互联网时代,用户对于网站的要求越来越高,不仅要求网站能够快速加载,还要求网站具有类似于原生应用的交互体验。而 PWA(Progressive Web App)技术,正是为了解决这一问题而出...

    1 年前
  • mongoose 操作 mongodb 数组的方法

    在使用 MongoDB 数据库时,经常需要操作文档中的数组数据。本文将介绍如何使用 Mongoose 驱动来操作 MongoDB 中的数组数据。 连接数据库 首先,我们需要使用 Mongoose 连接...

    1 年前
  • 解决使用 Custom Elements 时遇到的巨大的 DOM 问题

    随着 Web 应用程序变得越来越复杂,前端开发人员需要使用更多的工具和技术来管理和组织代码。其中一个重要的技术是 Custom Elements,它允许开发人员创建自定义 HTML 元素,以便更好地组...

    1 年前
  • ES9 中新增 symbol.asyncIterator 为异步迭代器提供基础

    在 ES9 中,新增了 symbol.asyncIterator,这为 JavaScript 异步迭代器提供了基础。异步迭代器是一种特殊的迭代器,它可以处理异步数据源,例如异步生成器或异步函数。

    1 年前
  • ES7 之走进修饰器装饰器的应用

    随着 JavaScript 语言的不断发展,ES7 中引入了修饰器装饰器的概念,这个概念对于前端开发者来说是一个重要的进步。修饰器装饰器可以帮助我们更好地组织和管理代码,提高代码的可读性和可维护性。

    1 年前
  • 如何在 Sequelize 中使用事务管理数据库操作?

    Sequelize 是一个 Node.js ORM(对象关系映射)框架,支持多种数据库,包括 MySQL、PostgreSQL、SQLite 和 Microsoft SQL Server 等。

    1 年前
  • Azure SDK 的性能优化:解决 Azure 经验中的性能问题

    前言 Azure SDK 是 Azure 云平台上的一组开发工具,用于帮助开发者在 Azure 上构建、部署和管理应用程序。Azure SDK 提供了多种编程语言的支持,包括 .NET、Java、Py...

    1 年前
  • ES8 中的异步函数让你的代码更加可读可维护

    在前端开发中,异步操作是不可避免的。在 ES6 中,Promise 和 async/await 已经让异步操作变得更加简洁和可读。而在 ES8 中,异步函数的引入更加方便了我们对异步操作的处理,使得代...

    1 年前
  • 如何优化 Angular SPA 应用的网络请求性能

    随着前端技术的不断发展,越来越多的网站和应用采用了单页应用(SPA)的架构。Angular 是一个流行的 SPA 框架,但是在网络请求方面,SPA 应用的性能往往不如传统的多页应用。

    1 年前
  • GraphQL 与数据生命周期的整合方案

    在前端开发中,我们经常需要处理数据的生命周期,包括数据的请求、缓存、更新、删除等等。而 GraphQL 作为一种新兴的数据查询语言,能够提供更加灵活、高效的数据处理方式。

    1 年前
  • 使用 Jest 进行 React Native 的集成测试

    前言 React Native 是一种流行的跨平台移动应用开发框架,它允许开发者使用 JavaScript 和 React 组件来构建 iOS 和 Android 应用。

    1 年前
  • CSS Reset 如何避免出现过度重置问题?

    前言 在进行前端开发时,我们经常会使用 CSS Reset 来消除不同浏览器对 HTML 元素默认样式的差异。然而,过度重置会导致我们的样式失效,影响页面的美观和用户体验。

    1 年前
  • 如何使用 ECMAScript 2019 重构你的 Promise 代码

    Promise 是 JavaScript 中常见的异步编程方式,它可以让我们更优雅地处理异步操作。随着 ECMAScript 的不断更新,Promise 在语言标准中也不断得到完善和扩展。

    1 年前
  • RxJS 操作符大全之常用情景篇

    RxJS 是一个强大的响应式编程库,它提供了一系列丰富的操作符来处理数据流。在前端开发中,我们经常需要处理异步数据和事件流,使用 RxJS 可以大大简化代码,并且提高代码的可维护性和可读性。

    1 年前
  • 在 React Native 项目中优化图片加载和缓存

    在移动应用开发中,图片是不可避免的资源。在 React Native 项目中,加载和缓存图片是一个很重要的优化点,可以提升应用的性能和用户体验。本文将介绍如何在 React Native 项目中优化图...

    1 年前

相关推荐

    暂无文章