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的其它相关数学基础,理论知识大家可以参看专栏的其它文章,这里不再赘述,本文就双容…...

测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

LeetCode - 394. 字符串解码
题目 394. 字符串解码 - 力扣(LeetCode) 思路 使用两个栈:一个存储重复次数,一个存储字符串 遍历输入字符串: 数字处理:遇到数字时,累积计算重复次数左括号处理:保存当前状态&a…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...

【论文阅读28】-CNN-BiLSTM-Attention-(2024)
本文把滑坡位移序列拆开、筛优质因子,再用 CNN-BiLSTM-Attention 来动态预测每个子序列,最后重构出总位移,预测效果超越传统模型。 文章目录 1 引言2 方法2.1 位移时间序列加性模型2.2 变分模态分解 (VMD) 具体步骤2.3.1 样本熵(S…...

AI书签管理工具开发全记录(十九):嵌入资源处理
1.前言 📝 在上一篇文章中,我们完成了书签的导入导出功能。本篇文章我们研究如何处理嵌入资源,方便后续将资源打包到一个可执行文件中。 2.embed介绍 🎯 Go 1.16 引入了革命性的 embed 包,彻底改变了静态资源管理的…...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...