「JS 基础」异步解决方案入门

前言
为了解决Javascript 语言的执行环境是单线程所带来的问题,Javascript 将任务的执行模式分为两种:同步和异步
同步即为后一个任务等待前一个任务结束再继续执行,程序的执行顺序与任务的排列顺序是一致的
异步则完全不同,每一个任务都有一个或者多个回调函数,前一个任务结束后,不是执行后一个任务而是执行回调函数,后一个任务则是不等待前一个任务执行结束就执行。因此,程序的执行顺序与任务的排列是不一致的、异步的。在浏览器端,耗时很长的操作都应该异步执行,从而避免浏览器失去响应。在服务端,异步模式甚至是唯一的模式,因为执行环境是单线程的,如果同步执行所有的 http 请求,服务器的性能会急剧下降。
异步解决方案
回调函数 callback
回调函数,简单来说就是一个函数作为参数传递给另一个函数
回调并不一定就是异步,并没有直接关系,只不过回调函数是异步的一种解决方案
// 同步
function fn1(callback){console.log("1")callback && callback()
}function fn2(){console.log("2")
}fn1(fn2)// 异步
function fn1(callback){setTimeout(() => {callback && callback()}, 1000)
}function fn2(){console.log("2")
}fn1(fn2)
缺点:
- 代码不优雅
- 不易阅读维护
- 高耦合,层层嵌套造成这种回调地狱
- 异步回调中,回调函数的执行栈与原函数分离开,外部无法抓住异常,异常会变得不可控
事件监听(发布订阅模式)
class EventEmitter {constructor() {this.events = {};}// 订阅指定的事件on(event, listener) {if (!this.events[event]) {this.events[event] = [];}this.events[event].push(listener);}// 取消订阅指定的事件off(event, listenerToRemove) {if (!this.events[event]) {return;}this.events[event] = this.events[event].filter(listener => listener !== listenerToRemove);}// 触发指定的事件,并传递数据给事件监听器emit(event, ...args) {if (!this.events[event]) {return;}this.events[event].forEach(listener => {listener.apply(this, args);});}
}// 使用 EventEmitter 的例子// 创建一个事件发射器的实例
const eventEmitter = new EventEmitter();// 创建监听事件
const onMessage = (message) => {console.log(`Received message: ${message}`);
};// 将监听器绑定到事件 'message'
eventEmitter.on('message', onMessage);// 触发事件 'message',并传递数据
eventEmitter.emit('message', 'Hello World!'); // 输出: Received message: Hello World!// 取消订阅
eventEmitter.off('message', onMessage);// 再次触发事件 'message',此时没有监听器监听这个事件,因此不会有输出
eventEmitter.emit('message', 'Hello again!');
Promise
ES6(ECMAScript 2015)引入了Promise,它是一种对异步操作进行管理的机制。Promise 代表一个尚未完成但预期将来会完成的异步操作的结果。它可以解决传统的回调地狱问题,提供更加优雅的异步代码管理方式,具备以下特点:
状态不可逆:Promise有三种状态:pending(进行中),fulfilled(已成功)和rejected(已失败)。状态改变只能从 pending 到 fulfilled 或从 pending 到 rejected,状态一旦改变,就不会再变。
异步结果的占位符:Promise 起到一个代理的作用,允许你在异步操作未完成时安排代码以响应式的成功(fulfilled)或失败(rejected)。
示例和基本用法:
// 创建一个新的 Promise 对象
let promise = new Promise(function(resolve, reject) {// 异步操作setTimeout(() => {// 成功的异步操作resolve('Data received');// 或者一个失败的异步操作// reject(new Error('Failed to receive data'));}, 1000);
});// 使用 then 方法设置当 promise 状态变为 fulfilled 时应该执行的代码
promise.then(function(value) {console.log(value);
}, function(error) {console.error(error);
});// 使用 catch 方法来捕获异常
promise.catch(function(error) {console.error('There was an error', error);
});
Promise的方法:
- then(onFulfilled, onRejected):then方法返回一个新的 Promise。它接受两个函数作为参数。第一个函数在Promise成功时调用,并接受成功的值作为参数。第二个函数在Promise失败时调用,并接受错误或拒绝的理由作为参数。
- catch(onRejected):捕获 Promise 中发生的任何异常,等同于.then(null, onRejected)。
- finally(onFinally):无论 Promise 最终的状态如何,都会执行onFinally回调,而且不接收任何参数。它通常用于清理操作,比如停止加载指示器。
此外,Promise API 还提供了几个静态方法用于处理多个Promise:
- Promise.all(iterable):接受一个 Promise 对象的集合作为输入,当这些对象全部成功时才触发成功。
- Promise.race(iterable):同样接受一个集合,但只要其中的一个 Promise 对象改变状态,返回的 promise 对象就会随之改变状态。
- Promise.resolve(value):返回一个以给定值解析后的 Promise 对象。
- Promise.reject(reason):返回一个以给定理由拒绝的 Promise 对象。
Promise 提高了异步代码的可读性和可维护性,并且是许多现代JavaScript异步编程的基石。
Async/Await
TODO
Async/Await = Generator + Promise
相关文章:
「JS 基础」异步解决方案入门
前言 为了解决Javascript 语言的执行环境是单线程所带来的问题,Javascript 将任务的执行模式分为两种:同步和异步 同步即为后一个任务等待前一个任务结束再继续执行,程序的执行顺序与任务的排列顺序是一致的 异步则完全不同,每…...
408学习笔记-16-C-动态内存管理
1、为什么要有动态内存分配 常规定义出来的变量,它们的大小都是已经规定好的,即在内存中开辟的内存空间都是固定的;且空间大小不可调整,可能会造成内存空间的浪费。 于是C语言引入了动态内存开辟功能,让程序员自己可…...
vuex - 21年的笔记 - 后续更新
vuex是什么 Vuex是实现组件全局状态(数据)管理的一种机制,方便的实现组件之间的数据的共享 使用vuex统一管理状态的好处 能够在vuex中集中管理共享的数据,易于开发和后期维护能够高效地实现组件之间的数据共享,提高…...
ngrok实现内网穿透
在使用jenkins进行自动化部署时,需要设置github的webhook钩子来触发构建,由于jenkins运行在自己的电脑上,因此需要通过内网穿透来接受http请求。 Install ngrok via Homebrew with the following command: brew install ngrok/ngrok/ngrokP…...
开发chrome扩展( 禁止指定域名使用插件)
mainfest.json: {"manifest_version": 3,"name": "ChatGPT学习","version": "0.0.2","description": "ChatGPT,GPT-4,Claude3,Midjourney,Stable Diffusion,AI,人工智能,AI","icons": {&quo…...
Flink:Lookup Join 实现与示例代码
本文要演示的是:在流上关联一张外部表(例如 MySQL 数据库中的一张维表),用于丰富流上的数据,实际上,这正是最普遍的 ”维表 Join“ 的实现方式。通过这种方式和外部维表关联时,依然能关联到最新变化的维度数据,所以才说这是 ”维表 Join“。Lookup Join 与 《Flink Tem…...
python基础知识(四)
if not x % 2 > if x % 2 ! 0 Python HTML和XML解析的第三方库是 Beautifull Soup 不属于软件设计原则是 自底向上 用来表示实体之间联系的是 二维表 当对关系R和S进行自然连接时,要求R和S含有一个或者多个共有的 属性(关系就是二维表)…...
论文笔记:Llama 2: Open Foundation and Fine-Tuned Chat Models
导语 Llama 2 是之前广受欢迎的开源大型语言模型 LLaMA 的新版本,该模型已公开发布,可用于研究和商业用途。本文记录了阅读该论文的一些关键笔记。 链接:https://arxiv.org/abs/2307.09288 1 引言 大型语言模型(LLMsÿ…...
Unity UGUI之Toggle基本了解
在Unity中,Toggle一般用于两种状态之间的切换,通常用于开关或复选框等功能。 它的基本属性如图: 其中, Interactable(可交互):指示Toggle是否可以与用户交互。设置为false时,禁用To…...
鸿蒙Harmony应用开发—ArkTS-全局UI方法(日期滑动选择器弹窗)
根据指定的日期范围创建日期滑动选择器,展示在弹窗上。 说明: 该组件从API Version 8开始支持。后续版本如有新增内容,则采用上角标单独标记该内容的起始版本。 本模块功能依赖UI的执行上下文,不可在UI上下文不明确的地方使用&…...
华岳M9制造企业管理软件业务流程 2/4
华岳M9制造企业管理软件业务流程 2/4 步骤3 初始一、应收账款初始余额二、应付账款初始余额三、出纳账项初始余额四、会计账项初始余额五、盘点入库六、存货细目七、存货属性设置八、存货存量控制九、存货价格管理十、月末处理 步骤4 技术一、存货目录二、存货细目三、仓库绑定…...
echarts geo地图加投影两种方法
方法1,geo中加多个地图图形,叠加。缩放时 可能会不一致,需要捕捉georoam事件,使下层的geo随着上层的geo一起缩放拖曳 geo: [{zlevel: 3,//geo显示级别,默认是0 【最顶层图形】map: BJ,//地图名roam: true,scaleLimit: …...
GPT实战系列-LangChain的Prompt提示模版构建
GPT实战系列-LangChain的Prompt提示模版构建 LangChain GPT实战系列-LangChain如何构建基通义千问的多工具链 GPT实战系列-构建多参数的自定义LangChain工具 GPT实战系列-通过Basetool构建自定义LangChain工具方法 GPT实战系列-一种构建LangChain自定义Tool工具的简单方法…...
Docker容器中的mysql自动备份脚本
Docker容器中的mysql自动备份脚本 1. 脚本功能 备份容器中的mysql数据库到宿主机上,自动删除7天前的备份文件 2. 脚本内容 #!/bin/bash # auth Eric source /etc/profile # 设置备份目录和文件名 backup_directory"/app/backup" #测试名字用%Y%m%d%H…...
品精酿啤酒:畅享生活,享受快乐
在现代社会,品牌营销策略对于产品的成功至关重要。Fendi club啤酒之所以能够成为畅享生活、享受时尚的代名词,与其品牌营销策略密不可分。 首先,Fendi club啤酒注重品牌形象的塑造。作为一个时尚品牌,Fendi club啤酒将时尚与品质融…...
进程创建,程序加载运行,以及进程终止,什么是僵尸进程,什么是孤儿进程
进程控制 创建进程,撤销进程,实现进程转换(必须一气呵成,使用原语) 原语不被中断是因为有关中断指令 创建进程 撤销进程 进程创建fork fork()函数会创建一个子进程,子进程会返…...
[python]bar_chart_race设置日期格式
1、设置日期标签的时间格式 # 设置日期格式,默认为%Y-%m-%dbcr.bar_chart_race(df, covid19_horiz.gif, period_fmt%b %-d, %Y) 2、更改日期标签为数值 # 设置日期标签为数值bcr.bar_chart_race(df.reset_index(dropTrue), covid19_horiz.gif, interpolate_period…...
Apache FtpServer在Windows上下载安装与使用
Apache FtpServer在Windows上下载安装与使用 1、Apache Ftp Server下载 进入apache官网 https://mina.apache.org/ftpserver-project/old-downloads.html 下载自己使用的版本。 Apache FtpServer 1.1.1及以下的版本需要JDK1.7的支持 Apache FtpServer 1.1.1以上的版本需要JDK…...
CVE-2024-24112 XMall后台管理系统 SQL 注入漏洞分析
------作者本科毕业设计项目 基于 Spring Boot Vue 开发而成...... [Affected Component] /item/list /item/listSearch /sys/log /order/list /member/list (need time-based blind injection) /member/list/remove 项目下载地址 Exrick/xmall: 基于SOA架构的分布式…...
jwt以及加密完善博客系统
目录 一、背景 二、传统登陆功能&强制登陆功能 1、传统的实现方式 2、session存在的问题 三、jwt--令牌技术 1、实现过程 2、令牌内容 3、生成令牌 4、检验令牌 四、JWT登陆功能&强制登陆功能 1、JWT实现登陆功能 2、强制登陆功能 3、运行效果 五、加密/加…...
uniapp 对接腾讯云IM群组成员管理(增删改查)
UniApp 实战:腾讯云IM群组成员管理(增删改查) 一、前言 在社交类App开发中,群组成员管理是核心功能之一。本文将基于UniApp框架,结合腾讯云IM SDK,详细讲解如何实现群组成员的增删改查全流程。 权限校验…...
vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
【C语言练习】080. 使用C语言实现简单的数据库操作
080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...
企业如何增强终端安全?
在数字化转型加速的今天,企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机,到工厂里的物联网设备、智能传感器,这些终端构成了企业与外部世界连接的 “神经末梢”。然而,随着远程办公的常态化和设备接入的爆炸式…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
蓝桥杯 冶炼金属
原题目链接 🔧 冶炼金属转换率推测题解 📜 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V,是一个正整数,表示每 V V V 个普通金属 O O O 可以冶炼出 …...
HarmonyOS运动开发:如何用mpchart绘制运动配速图表
##鸿蒙核心技术##运动开发##Sensor Service Kit(传感器服务)# 前言 在运动类应用中,运动数据的可视化是提升用户体验的重要环节。通过直观的图表展示运动过程中的关键数据,如配速、距离、卡路里消耗等,用户可以更清晰…...
【7色560页】职场可视化逻辑图高级数据分析PPT模版
7种色调职场工作汇报PPT,橙蓝、黑红、红蓝、蓝橙灰、浅蓝、浅绿、深蓝七种色调模版 【7色560页】职场可视化逻辑图高级数据分析PPT模版:职场可视化逻辑图分析PPT模版https://pan.quark.cn/s/78aeabbd92d1...
JS设计模式(4):观察者模式
JS设计模式(4):观察者模式 一、引入 在开发中,我们经常会遇到这样的场景:一个对象的状态变化需要自动通知其他对象,比如: 电商平台中,商品库存变化时需要通知所有订阅该商品的用户;新闻网站中࿰…...
