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

Cesium1.95中高性能加载1500个点

一、基本方式&#xff1a; 图标使用.png比.svg性能要好 <template><div id"cesiumContainer"></div><div class"toolbar"><button id"resetButton">重新生成点</button><span id"countDisplay&qu…...

ssc377d修改flash分区大小

1、flash的分区默认分配16M、 / # df -h Filesystem Size Used Available Use% Mounted on /dev/root 1.9M 1.9M 0 100% / /dev/mtdblock4 3.0M...

Leetcode 3577. Count the Number of Computer Unlocking Permutations

Leetcode 3577. Count the Number of Computer Unlocking Permutations 1. 解题思路2. 代码实现 题目链接&#xff1a;3577. Count the Number of Computer Unlocking Permutations 1. 解题思路 这一题其实就是一个脑筋急转弯&#xff0c;要想要能够将所有的电脑解锁&#x…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台

🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...

Unsafe Fileupload篇补充-木马的详细教程与木马分享(中国蚁剑方式)

在之前的皮卡丘靶场第九期Unsafe Fileupload篇中我们学习了木马的原理并且学了一个简单的木马文件 本期内容是为了更好的为大家解释木马&#xff08;服务器方面的&#xff09;的原理&#xff0c;连接&#xff0c;以及各种木马及连接工具的分享 文件木马&#xff1a;https://w…...

iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈

在日常iOS开发过程中&#xff0c;性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期&#xff0c;开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发&#xff0c;但背后往往隐藏着系统资源调度不当…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...

【Android】Android 开发 ADB 常用指令

查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...

MySQL:分区的基本使用

目录 一、什么是分区二、有什么作用三、分类四、创建分区五、删除分区 一、什么是分区 MySQL 分区&#xff08;Partitioning&#xff09;是一种将单张表的数据逻辑上拆分成多个物理部分的技术。这些物理部分&#xff08;分区&#xff09;可以独立存储、管理和优化&#xff0c;…...

第一篇:Liunx环境下搭建PaddlePaddle 3.0基础环境(Liunx Centos8.5安装Python3.10+pip3.10)

第一篇&#xff1a;Liunx环境下搭建PaddlePaddle 3.0基础环境&#xff08;Liunx Centos8.5安装Python3.10pip3.10&#xff09; 一&#xff1a;前言二&#xff1a;安装编译依赖二&#xff1a;安装Python3.10三&#xff1a;安装PIP3.10四&#xff1a;安装Paddlepaddle基础框架4.1…...