当前位置: 首页 > news >正文

JavaScript中的异步编程

当我们在编写JavaScript代码时,经常会遇到需要执行长时间运行的任务的情况,例如从服务器获取数据或进行复杂的计算。在这些情况下,我们不希望阻塞用户界面,因为这会使网站看起来卡顿,甚至无响应。为了避免这种情况,我们需要使用JavaScript中的异步编程技术。

异步编程是JavaScript中的一个核心概念,它使我们能够在执行长时间运行的任务时不会阻塞用户界面,而是在任务完成后立即返回结果。本文将介绍JavaScript中的异步编程方式,并探讨它们的优缺点,以及如何使用它们来解决常见的异步编程问题。

一、回调函数

回调函数是JavaScript中最早和最基本的异步编程方式。它通过在函数参数中传递一个函数,让我们能够在异步操作完成后调用该函数。例如,我们可以使用XMLHttpRequest对象从服务器获取数据:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://example.com/data');
xhr.onreadystatechange = function() {if (xhr.readyState === 4 && xhr.status === 200) {console.log(xhr.responseText);}
};
xhr.send();

在上面的例子中,我们定义了一个XMLHttpRequest对象,然后使用open()方法设置请求的类型和URL。然后,我们为onreadystatechange属性指定了一个函数,当readyState属性变为4且状态码为200时,该函数将被调用。在该函数中,我们可以访问响应文本并在控制台中打印它。

虽然回调函数是JavaScript中最早和最基本的异步编程方式,但它有一些缺点。首先,如果我们需要进行嵌套异步操作,回调函数将变得非常复杂和难以理解。其次,回调函数容易出现回调地狱问题,这是指代码中有太多的回调函数,使得代码难以维护和扩展。

二、Promise

为了解决回调地狱问题,JavaScript引入了Promise,它是一种更加高级的异步编程方式。Promise通过将异步操作的结果封装在一个对象中,使得我们可以更加清晰和简洁地处理异步操作。例如,我们可以使用Promise从服务器获取数据:

fetch('https://example.com/data').then(response => response.text()).then(text => console.log(text)).catch(error => console.error(error));

在上面的例子中,我们使用fetch()方法发起一个HTTP请求,并将其封装在一个Promise对象中。然后,我们使用.then()方法指定一个函数,当Promise对象的状态变为fulfilled时将被调用。在这个函数中,我们可以访问响应对象并将其转换为文本。然后,我们使用.then()方法指定另一个函数,当上一个Promise对象的状态变为fulfilled时将被调用。在这个函数中,我们可以访问响应文本并在控制台中打印它。最后,我们使用.catch()方法指定一个函数,当Promise对象的状态变为rejected时将被调用。在这个函数中,我们可以处理错误。

Promise还提供了一些其他的方法,如Promise.all()和Promise.race()。Promise.all()可以同时处理多个Promise对象,并在所有Promise对象都变为fulfilled时返回一个包含所有结果的数组。例如:

Promise.all([fetch('https://example.com/data1'),fetch('https://example.com/data2')
]).then(responses => Promise.all(responses.map(response => response.text()))).then(texts => console.log(texts)).catch(error => console.error(error));

在上面的例子中,我们使用Promise.all()方法同时发起两个HTTP请求,并将它们封装在一个数组中。然后,我们使用.then()方法指定一个函数,该函数将结果数组作为参数,并使用Promise.all()方法将结果数组中的所有响应对象转换为文本。最后,我们使用.then()方法指定另一个函数,该函数将文本数组作为参数并在控制台中打印它们。

Promise.race()可以处理多个Promise对象,并在第一个Promise对象变为fulfilled或rejected时返回它的结果。例如:

Promise.race([new Promise(resolve => setTimeout(() => resolve('foo'), 2000)),new Promise((resolve, reject) => setTimeout(() => reject(new Error('bar')), 1000))
]).then(result => console.log(result)).catch(error => console.error(error));

在上面的例子中,我们使用Promise.race()方法处理两个Promise对象,其中一个会在2秒后返回字符串'foo',另一个会在1秒后返回一个错误对象。由于第二个Promise对象先返回结果,所以Promise.race()返回错误对象并在.catch()方法中处理它。

三、async/await

async/await是ES2017中引入的一种异步编程方式,它建立在Promise之上,并提供了更加简洁和直观的语法。async/await使用async函数来表示异步操作,并使用await关键字来等待Promise对象的完成。例如,我们可以使用async/await从服务器获取数据:

async function getData() {try {const response = await fetch('https://example.com/data');const text = await response.text();console.log(text);} catch (error) {console.error(error);}
}
getData();

在上面的例子中,我们定义了一个async函数getData(),并在其中使用await关键字等待fetch()方法返回一个响应对象。然后,我们再次使用await关键字等待将响应对象转换为文本。最后,我们可以在控制台中打印文本或处理错误。

与Promise一样,async/await也支持多个异步操作的处理。例如,我们可以使用Promise.all()和async/await同时处理多个Promise对象:

async function getData() {try {const responses = await Promise.all([fetch('https://example.com/data1'),fetch('https://example.com/data2')]);const texts = await Promise.all(responses.map(response => response.text()));console.log(texts);} catch (error) {console.error(error);}
}
getData();


在上面的例子中,我们定义了一个async函数getData(),并在其中使用Promise.all()方法同时发起两个HTTP请求并等待它们完成。然后,我们使用await关键字等待将响应对象转换为文本,并将所有结果放入一个数组中。最后,我们可以在控制台中打印文本数组或处理错误。

总结

JavaScript是一门强大的编程语言,具有异步编程的优势。在本文中,我们介绍了三种常见的异步编程方式:回调函数、Promise和async/await。回调函数是异步编程的基础,但它的嵌套结构和错误处理使得代码难以维护。Promise是回调函数的一种改进,它通过链式调用和错误处理提供了更好的可读性和可维护性。最后,async/await建立在Promise之上,提供了更加简洁和直观的语法。当我们需要处理多个异步操作时,Promise.all()和Promise.race()提供了一种有效的方法。无论是哪种方式,我们都可以在JavaScript中使用异步编程来实现更好的性能和用户体验。
 

相关文章:

JavaScript中的异步编程

当我们在编写JavaScript代码时,经常会遇到需要执行长时间运行的任务的情况,例如从服务器获取数据或进行复杂的计算。在这些情况下,我们不希望阻塞用户界面,因为这会使网站看起来卡顿,甚至无响应。为了避免这种情况&…...

奥斯汀独家对话|从机构的「拉扯」中成长的美国加密监管

‍前言 4月25日,在美国得克萨斯州的首府奥斯汀,这座充满活力和创造力的城市,欧科云链研究院与来自哥伦比亚商学院的Austin Campbell教授就美国加密监管以及其相关话题进行了一次深入探讨。双方讨论了美国整体的监管问题、监管逻辑、最新的稳…...

PostgreSQL16中pg_dump的LZ4和ZSTD压缩

PostgreSQL16中pg_dump的LZ4和ZSTD压缩 pg_dump压缩lz4和zstd LZ4和ZSTD压缩算法合入了PG16。LZ4补丁的作者是Georgios Kokolatos。由Tomas Vondra提交。由Michael Paquier、Rachel Heaton、Justin Pryzby、Shi Yu 和 Tomas Vondra 审阅。提交消息是: Expand pg_dum…...

网络安全基础入门学习路线

在大多数的思维里总觉得学习网络安全得先收集资料、学习编程、学习计算机基础,这样不是不可以,但是这样学效率太低了! 你要知道网络安全是一门技术,任何技术的学习一定是以实践为主的。也就是说很多的理论知识其实是可以在实践中…...

错误检测技术:奇偶校验

文章目录 参考描述奇校验与偶校验错误检测技术奇偶校验 奇校验与偶校验奇校验偶校验局限性漏网之鱼 奇偶校验的三种形式水平奇偶校验垂直奇偶校验水平垂直奇偶校验优劣漏网之鱼 参考 项目描述搜索引擎Google 、Bing百度百科奇偶校验计算机网络 基础与应用(微课版&a…...

语义版本控制规范(SemVer)

Semantic Versioning 2.0.0 官网 给出一个版本号MAJOR.MINOR.PATCH,增加如下: MAJOR version 进行不兼容的API更改时MINOR version 当您以向后兼容的方式添加功能时PATCH version 当您进行向后兼容的错误修复时 预发布(pre-release )和构建元数据的附…...

基于Flask的留言板的设计与实现

这是《Flask Web开发实战:入门、进阶与原理解析》这本书中的一个小项目,我在学习后根据书中的教程实现了留言板的功能,并结合我的思路将代码做了一些调整。 下面这是实现后的展示图片 文章目录 设计思路项目代码exts.pymodels.pyforms.pyerrors.pycomma…...

vmware 详细安装教程

一.VM是什么? VMware Workstation是一个“虚拟 PC”软件。它使你可以在一台机器上同时运行二个或更多 Windows、DOS、LINUX 系统。与“多启动”系统相比,VMWare 采用了完全不同的概念。多启动系统在一个时刻只能运行一个系统,在系统切换时需…...

Python 爬虫工具

Python3 默认提供了urllib库,可以爬取网页信息,但其中确实有不方便的地方,如:处理网页验证和Cookies,以及Hander头信息处理。 为了更加方便处理,有了更为强大的库 urllib3 和 requests, 本节会分别介绍一下…...

再也不去字节跳动面试了,6年测开经验的真实面试经历.....

前几天我朋友跟我吐苦水,这波面试又把他打击到了,做了快6年软件测试员。。。为了进大厂,也花了很多时间和精力在面试准备上,也刷了很多题。但题刷多了之后有点怀疑人生,不知道刷的这些题在之后的工作中能不能用到&…...

第十五章 角色移动旋转实例

本章节我们创建一个“RoleDemoProject”工程,然后导入我们之前创建地形章节中的“TerrainDemo.unitypackage”资源包,这个场景很大,大家需要调整场景视角才能看清。 接下来,我们添加一个人物模型,操作方式就是将模型文…...

数据湖Data Lakehouse支持行级更改的策略:COW、MOR、Delete+Insert

COW:写时复制,MOR:读时合并,Delete+Insert:保证同一个主键下仅存在一条记录,将更新操作转换为Delete操作和Insert操作 COW和MOR的对比如下图,而Delete+Insert在StarRocks主键模型中用到。 目前COW、MOR在三大开源数据湖项目的使用情况,如下图。 写入时复制【Copy-On…...

双亲委派机制的原理和作用

双亲委派机制,就必须弄清楚Java的类加载器。 什么是类加载器 Java类加载器(ClassLoader)是Java运行时环境(JRE)的一部分,负责动态的将Java类加载到Java虚拟机的内存空间。 类加载器有哪些 主要有三个: 引导类加载器(Bootstrap ClassLoade…...

mac免费杀毒软件哪个好用?如何清理mac系统需要垃圾

CleanMyMac x是一款功能强大的Mac系统优化清理工具,使用旨在帮助用户更加方便的清理您系统中的所有垃圾,从而加快电脑运行速度,保持最佳性能,更加稳定、流畅、快速!!! CleanMyMac X无疑是目前m…...

css 实现太极效果

目录 一、简述二、太极效果制作 一、简述 本次主要介绍::after,::before,box-shadow这三个属性。 ::after,::before这两个是伪类选择器,box-shaow是用来设置元素的阴影效果 before:向选定的元素前插入内容 after:向选定的元素后插…...

【前端基础知识】Vue中的变量不是响应式的吗?属性赋值后视图不变化的原因是什么?

目录 🤔问题📝回答🎨使用场景动态添加属性动态添加数组元素 ❌注意事项$set只能在响应式对象上使用$set不能用于根级别的属性$set的性能问题 📄总结 🤔问题 Vue是一款在国内非常流行的框架,采用MVVM架构&a…...

如何完全卸载linux下通过rpm安装的mysql

卸载linux下通过rpm安装的mysql 1.关闭MySQL服务2.使用 rpm 命令的方式查看已安装的mysql3. 使用rpm -ev 命令移除安装4. 查询是否还存在遗漏文件5. 删除MySQL数据库内容 1.关闭MySQL服务 如果之前安装过并已经启动,则需要卸载前请先关闭MySQL服务 systemctl stop…...

[渗透教程]-004-长城防火墙GFW的原理

文章目录 1. baidu.com 请求过程2. GFW原理2.1 GFW拦截方法1:DNS渲染2.2 通过IP黑名单2.3 VPN阻断1. baidu.com 请求过程 家庭的路由器具备了交换机的功能.域名–>ip,优先检测本地的缓存,没有的话就查找DNS服务器,传输层对应该层的数据进行封装增加了端口的信息,网络层对传输…...

LaTeX基础文本排版命令

LaTeX基础文本排版命令 1. 字体大小2. 字体的粗体与斜体2.1. 粗体2.2 斜体2.3 同时启用粗体和斜体 3. 空格长度4. 高度与宽度尺寸 在LaTeX中,文本排版可以通过简单的命令实现,这些命令可以控制字体大小、粗体与斜体、空格、行高和宽度等方面,…...

PLC模糊控制模糊PID(梯形图实现+算法分析)

博途PLC的模糊PID控制详细内容请查看下面的博客文章: Matlab仿真+博途PLC模糊PID控制完整SCL源代码参考(带模糊和普通PID切换功能)_博途怎么实现模糊pid_RXXW_Dor的博客-CSDN博客模糊PID的其它相关数学基础,理论知识大家可以参看专栏的其它文章,这里不再赘述,本文就双容…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

基于数字孪生的水厂可视化平台建设:架构与实践

分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

leetcodeSQL解题:3564. 季节性销售分析

leetcodeSQL解题:3564. 季节性销售分析 题目: 表:sales ---------------------- | Column Name | Type | ---------------------- | sale_id | int | | product_id | int | | sale_date | date | | quantity | int | | price | decimal | -…...

laravel8+vue3.0+element-plus搭建方法

创建 laravel8 项目 composer create-project --prefer-dist laravel/laravel laravel8 8.* 安装 laravel/ui composer require laravel/ui 修改 package.json 文件 "devDependencies": {"vue/compiler-sfc": "^3.0.7","axios": …...

智能AI电话机器人系统的识别能力现状与发展水平

一、引言 随着人工智能技术的飞速发展,AI电话机器人系统已经从简单的自动应答工具演变为具备复杂交互能力的智能助手。这类系统结合了语音识别、自然语言处理、情感计算和机器学习等多项前沿技术,在客户服务、营销推广、信息查询等领域发挥着越来越重要…...

mac 安装homebrew (nvm 及git)

mac 安装nvm 及git 万恶之源 mac 安装这些东西离不开Xcode。及homebrew 一、先说安装git步骤 通用: 方法一:使用 Homebrew 安装 Git(推荐) 步骤如下:打开终端(Terminal.app) 1.安装 Homebrew…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

Qt 事件处理中 return 的深入解析

Qt 事件处理中 return 的深入解析 在 Qt 事件处理中,return 语句的使用是另一个关键概念,它与 event->accept()/event->ignore() 密切相关但作用不同。让我们详细分析一下它们之间的关系和工作原理。 核心区别:不同层级的事件处理 方…...