一篇带你看懂异步:promise、async await
在前端开发中,特别是使用Vue.js框架时,Promises(承诺)和resolve是与异步操作相关的重要概念。让我来解释一下它们的含义和如何在Vue.js中使用它们。
一、Promise
1. Promise(承诺):
Promise是一种处理异步操作的对象,它表示一个可能还没有完成的操作,但在未来会完成。Promise有三个状态:pending(待定)、fulfilled(已完成)和rejected(已拒绝)。Promise允许执行异步操作并在操作完成时执行回调函数。
2. 使用场景:
Vue.js以及其他现代JavaScript框架广泛使用Promise来处理异步操作,如HTTP请求、定时器等。
const myPromise = new Promise((resolve, reject) => {// 异步操作,例如从服务器获取数据if (/* 操作成功 */) {resolve("操作成功"); // 操作成功后调用resolve} else {reject("操作失败"); // 操作失败后调用reject}
});myPromise.then((result) => {console.log(result); // 在操作成功时执行
}).catch((error) => {console.error(error); // 在操作失败时执行
});
示例中,首先执行了以下部分:
const myPromise = new Promise((resolve, reject) => {
if (/* 操作成功 */) {// 异步操作成功后,调用resolveresolve("操作成功");
} else {reject("操作失败"); // 操作失败后调用reject}
});
这部分是创建一个Promise对象,并在内部的回调函数中执行异步操作。在这个回调函数中,我们使用了resolve,表示异步操作成功。如果异步操作失败,可以使用reject 来表示操作失败。
resolve是Promise对象内部的一个函数,用于将Promise状态从pending(待定)变为fulfilled(已完成)。reject 同理。
接下来,我们可以使用.then()和.catch()来处理Promise的状态变化:
-
.then()方法用于处理Promise对象状态从pending到fulfilled(已完成)的情况。在这个函数中,可以访问异步操作成功时的结果。 -
.catch()方法用于处理Promise对象状态从pending到rejected(已拒绝)的情况。在这个函数中,可以访问异步操作失败时的错误信息。
在的示例中,在异步操作成功后调用resolve来指示Promise已经成功完成,并且Promise状态变为fulfilled,将结果传递给后续的.then()回调函数,所以会执行.then()回调,打印出"操作成功"。
如果在Promise构造函数中调用了reject,那么Promise状态会变为rejected,并且会执行.catch()回调,可以在该回调中处理异步操作的失败情况。
3. 使用方法、场景
第一个示例:我们创建了一个Promise实例,并将其存储在名为 myPromise 的变量中。这个Promise实例的作用域限定在当前代码块(通常是一个函数),可以在这个函数内部的任何位置使用它。例如:
function myFunction() {const myPromise = new Promise((resolve, reject) => {// 异步操作,使用 resolve 或 reject});// 在函数内的任何位置都可以使用 myPromisemyPromise.then((result) => {// 处理成功的情况}).catch((error) => {// 处理失败的情况});
}
在上述示例中,myPromise 是函数 myFunction 内部的一个变量,可以在函数内的任何地方使用它。
第二个示例:get(opt) 函数返回一个新的Promise实例。这意味着每次调用 get(opt) 函数时,都会创建一个新的Promise实例。这些实例是与函数调用无关的,它们不共享状态或数据。例如:
function get(opt) {return new Promise((resolve, reject) => {// 异步操作,使用 resolve 或 reject});
}const promise1 = get(someOption); // 创建第一个Promise实例
const promise2 = get(anotherOption); // 创建第二个Promise实例
在上述示例中,promise1 和 promise2 是两个不同的Promise实例,它们与函数调用无关。每个函数调用都会返回一个新的独立Promise实例。
如果在整个系统中的多个地方都需要使用相同的Promise实例,那么第一种方法将创建一个共享的Promise实例,多处调用都将共享相同的状态和数据。这可以用于在多个地方共享相同的异步操作结果。
而第二种方法,每次调用 get() 都会创建一个新的、独立的Promise实例,这些实例之间是相互独立的,不会共享状态或数据。这适用于需要在不同地方使用不同的异步操作的情况。
如果需要在多个地方共享相同的异步操作结果,第一种方法可能更合适。如果需要在不同地方使用独立的异步操作,第二种方法更适合。
4.Promise的链式写法
Promise的链式写法是一种结构化的方式,用于在处理异步操作时按顺序执行一系列操作。这种写法可以让清晰地组织和控制异步操作的流程。在这种写法中,通过使用.then()方法将多个回调函数链接在一起,每个回调函数返回一个新的Promise对象,从而允许顺序执行多个异步操作。
一个典型的Promise链式写法如下:
someAsyncFunction().then((result1) => {// 处理 result1,可以返回一个新的Promisereturn someOtherAsyncFunction(result1);}).then((result2) => {// 处理 result2,可以返回一个新的Promisereturn anotherAsyncFunction(result2);}).then((result3) => {// 处理 result3}).catch((error) => {// 处理任何发生的错误});
在上面的示例中,首先调用了someAsyncFunction(),然后通过.then()方法将多个回调函数连接在一起,每个.then()回调接受上一个.then()回调的结果并返回一个新的Promise。这允许按顺序执行异步操作,并且每个.then()中的操作都可以处理前一个操作的结果。
如果任何地方发生了错误,它将被捕获并传递给.catch()块进行处理。
链式写法的好处在于它使异步操作的顺序和控制更加明确,而不需要嵌套回调,从而提高了可读性和维护性。这种结构也使你能够有效地处理异步操作之间的依赖关系,因为每个.then()中的操作依赖于前一个操作的结果。
在Promise的链式写法中,通常不需要显式地传递(resolve, reject),因为.then() 和 .catch() 方法会自动处理Promise的状态和结果。这是Promise的一种抽象方式,它隐藏了底层的resolve和reject。
在链式写法中,.then() 方法用于处理Promise的成功状态,而 .catch() 方法用于处理Promise的失败状态。这两个方法接收一个回调函数作为参数,这个回调函数会自动接收前一个Promise的结果或错误。如果前一个Promise成功,.then()回调将被执行,如果前一个Promise失败,.catch()回调将被执行。例如:
someAsyncFunction().then((result) => {// 这个回调处理成功状态console.log(result);}).catch((error) => {// 这个回调处理失败状态console.error(error);});
二、async await
1)当谈到JavaScript中的异步编程时,async/await 是一种非常强大和直观的方法。它是在ECMAScript 2017 (ES8) 中引入的,用于简化Promise的使用和管理异步操作。
1. async 函数:
async函数是一个特殊的函数关键字,它用于声明一个异步函数。异步函数将始终返回一个Promise对象。- 异步函数可以包含
await表达式,以等待其他异步操作完成。
示例:
async function fetchData() {// 异步操作
}
2. await 表达式:
await只能在async函数内部使用,它用于等待一个Promise解决为其值。await将暂停函数的执行,直到等待的Promise完成(无论成功或失败)并返回结果。
示例:
async function fetchAndProcessData() {const data = await fetchData(); // 等待fetchData()的完成// 在这里可以使用data
}
3. 错误处理:
- 使用
try/catch来捕获await表达式引发的错误。 - 可以使用普通的同步错误处理机制来处理
async/await中的错误。
示例:
async function fetchAndProcessData() {try {const data = await fetchData();// 处理成功情况} catch (error) {// 处理错误情况}
}
4. 并行操作:
- 使用多个
await表达式可以在某种程度上实现并行操作,等待多个异步操作同时完成。 - 这可以提高性能,但要注意不要过度并行,以避免不必要的竞争条件。
示例:
async function fetchAndProcessData() {const result1 = await fetchFirstData();const result2 = await fetchSecondData();// result1和result2将顺序完成
}
5. 顺序执行:
async/await确保异步操作按照它们的声明顺序执行,从而更容易理解和维护异步代码。
示例:
async function fetchAndProcessData() {const result1 = await fetchFirstData();const result2 = await process(result1);const result3 = await fetchSecondData(result2);// 每个操作都在前一个操作完成后执行
}
2)当涉及到异步编程时,
async/await在许多常见场景中都非常有用。以下是一些常用场景:
1. 发起网络请求:async/await 可以用于发起HTTP请求,等待响应,并处理返回的数据。这对于处理API调用、获取远程数据等非常有用。
async function fetchData() {try {const response = await fetch('https://api.example.com/data');const data = await response.json();// 处理返回的数据} catch (error) {// 处理错误}
2. 文件操作:在Node.js中,async/await 可以用于执行文件读取、写入等操作。这使得处理文件系统操作更加方便。
const fs = require('fs').promises;async function readFile() {try {const content = await fs.readFile('file.txt', 'utf-8');// 处理文件内容} catch (error) {// 处理错误}
3. 循环操作:async/await 可以用于按顺序处理循环中的项目,确保每个项目的处理都完成后再进行下一个。
async function processItems(items) {for (const item of items) {const result = await processItem(item);// 处理每个项目的结果}
4. 多个并行操作:通过使用 Promise.all 结合 async/await,可以实现多个并行异步操作,以提高性能。
async function parallelOperations() {const results = await Promise.all([asyncOperation1(),asyncOperation2(),asyncOperation3()]);// 处理所有操作的结果
5. 错误处理:async/await 简化了错误处理,通过 try/catch 可以捕获异步操作中的错误。
async function someAsyncTask() {try {// 异步操作} catch (error) {// 处理错误}
三、promise和async await
能用async await的地方也能用promise的链式写法
await后面的代码相当于then的回调,也就是微任务,加入微任务队列,然后js继续执行其他代码,等到同步任务执行完了再去微任务队列取出来(先进先出原则)。
1. async关键字用于修饰函数,被它修饰的函数,一定返回Promise。
2. await 关键字表示等待某个Promise完成,它必须用于 async 函数中。
相关文章:
一篇带你看懂异步:promise、async await
在前端开发中,特别是使用Vue.js框架时,Promises(承诺)和resolve是与异步操作相关的重要概念。让我来解释一下它们的含义和如何在Vue.js中使用它们。 一、Promise 1. Promise(承诺): Promise是一种处理异…...
RocketMQ快速实战以及集群架构详解
文章目录 一、MQ简介二、RocketMQ产品特点RocketMQ介绍RocketMQ特点 三、RocketMQ快速实战快速实现消息收发命令行快速实现消息收发搭建Maven客户端项目 搭建RocketMQ可视化管理服务 四、升级分布式集群五、升级高可用集群六、总结RocketMQ的运行架构七、理解RocketMQ的消息模型…...
京东运营数据分析:2023年8月京东饮料行业品牌销售排行榜
鲸参谋监测的京东平台8月份饮料市场销售数据已出炉! 8月份,饮料市场整体销售下滑。根据鲸参谋电商数据分析平台的相关数据显示,今年8月,京东平台饮料市场的总销量将近820万,环比下滑约8%,同比下滑约20%&am…...
ES6之函数的扩展二
ES6之函数的扩展一 传送门 9.3 函数length属性 函数的length属性,不包含rest参数 console.log((function (a) {}).length) // 1 console.log((function (...a) {}).length) // 0 console.log((function (a1,b,...a) {}).length) // 210:严格模式 在 …...
Ubuntu-Ports更新源 ARM64更新源
Ubuntu-Ports更新源 Ubuntu ARM64更新源 简介: Arm64,Armhf等平台的Ubuntu软件仓库。 Ubuntu-Ports国内镜像源 华为镜像Ubuntu-Ports 阿里云镜像Ubuntu-Ports 清华大学镜像Ubuntu-Ports 改用清华大学镜像更新源 Ubuntu 的软件源配置文件是 /etc/ap…...
渗透测试怎么入门?(超详细解读)
1. 什么是渗透测试 渗透测试就是模拟真实黑客的攻击手法对目标网站或主机进行全面的安全评估,与黑客攻击不一样的是,渗透测试的目的是尽可能多地发现安全漏洞,而真实黑客攻击只要发现一处入侵点即可以进入目标系统。 一名优秀的渗透测试工程…...
MS31804四通道低边驱动器可pin对pin兼容DRV8804
MS31804TE 是一个具有过流保护功能的四通道低边驱动器。MS31804TE 内置钳位二极管,用来钳制由电感负载续流产生的电压。MS31804TE 可以驱动单极步进电机、直流电机、继电器、螺线管或者其它负载。 散热良好的情况下,MS31804TE 可以提供每个通道最高 2A 的…...
Fastadmin 子级菜单展开合并,分类父级归纳
这里踩过一个坑,fastadmin默认的展开合并预定义处理的变量是pid。 所以建表时父级id需要是pid; 当然不是pid也没关系,这里以cat_id为例,多加一步处理一样能实现。 废话少说上代码: 首先在控制器, 引用…...
Idea创建springboot工程的时候,发现pom文件没有带<parent>标签
今天创建springboot工程,加载maven的时候报错: 这个问题以前遇到过,这是因为 mysql-connector-j 没有带版本号的原因,但是springboot的依赖的版本号不是都统一交给spring-boot-starter-parent管理了吗,为什么还会报错&…...
element树形控件编辑节点组装节点
需求功能: 编辑树节点,组装节点 <el-scrollbar class"scrollbar-wrapper"><el-tree :data"nodeList" ref"tree" :props"defaultProps" :expand-on-click-node"false"><template slot…...
【算法-动态规划】斐波那契第 n 项
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kuan 的首页,持续学…...
Linux系统运行级别详解,切换、配置和常见服务
文章目录 Linux系统运行级别1. 介绍什么是系统运行级别系统运行级别的作用 2. Linux系统运行级别Linux系统预定义的运行级别每个运行级别的作用和特点 3. 切换系统运行级别如何查看当前系统运行级别如何切换到其他运行级别切换运行级别时需要注意的事项 4. 运行级别相关的服务和…...
企业需要ERP系统的八大理由,最后一个尤其重要
许多企业仍在质疑自己是否真的需要**ERP系统**。日常事务已经非常繁重,如果再加上寻找和实施一个新系统的挑战,那就更麻烦了。 公司业务在不断发展,出现了一些增长,订单也在不断增加,扭亏为盈,总体来说还算…...
Java-Atomic原子操作类详解及源码分析,Java原子操作类进阶,LongAdder源码分析
文章目录 一、Java原子操作类概述1、什么是原子操作类2、为什么要用原子操作类3、CAS入门 二、基本类型原子类1、概述2、代码实例 三、数组类型原子类1、概述2、代码实例 四、引用类型原子类1、概述2、AtomicReference3、ABA问题与AtomicStampedReference4、一次性修改…...
算法通过村第十二关-字符串|黄金笔记|冲刺难题
文章目录 前言最长公共前缀纵向比较横向比较 字符串压缩问题表示数值的字符串总结 前言 提示:我有时候在想,我是真的不太需要其他人,还是因为跟他们在一起时没法自己,所以才保持距离。我们的交谈就像是平行而毫无交集的自言自语。…...
3ds Max渲染太慢?创意云“一键云渲染”提升3ds Max渲染体验
在数字艺术设计领域,3ds Max是广泛使用的三维建模和渲染软件之一。然而,许多用户都面临着一个共同的问题:渲染速度太慢。渲染一帧画面需要耗费数小时,让人无法忍受。除了之前给大家介绍的几种解决方法外: …...
记录一次公益SRC的常见的cookie注入漏洞(适合初学者)
目录 谷歌语法-信息收集 cookie注入 实战演示 信息收集 SQL注入判断 查找字段数 爆破表名 输出结果 总结 hack渗透视频教程,扫码免费领 谷歌语法-信息收集 1.查找带有ID传参的网站(可以查找sql注入漏洞) inurl:asp idxx 2.查找网站后…...
[ACTF2020 新生赛]Exec1
拿到题目,不知道是sql注入还是命令执行漏洞 先ping一下主机 有回显,说明是命令执行漏洞 我们尝试去查看目录 127.0.0.1|ls,发现有回显,目录下面有个index.php的文件 我们之间访问index.php 输入127.0.0.1;cat index.php 发现又…...
DeepFace【部署 03】轻量级人脸识别和面部属性分析框架deepface在Linux环境下服务部署(conda虚拟环境+docker)
Linux环境下服务部署 1.使用虚拟环境[810ms]1.1 环境部署1.2 服务启动 2.使用Docker[680ms] 1.使用虚拟环境[810ms] 1.1 环境部署 Anaconda的安装步骤这里不再介绍,直接开始使用。 # 1.创建虚拟环境 conda create -n deepface python3.9.18# 2.激活虚拟环境 cond…...
vuex的求和案例和mapstate,mapmutations,mapgetters
main.js import Vue from vue import App from ./App.vue //引入vuex import Vuex from vuex //引入store import store from ./store/indexVue.config.productionTip falsenew Vue({el:"#app",render: h > h(App),store,beforeCreate(){Vue.prototype.$bus th…...
信息系统项目管理师核心知识点精讲
一、项目整合管理(重点:项目章程与项目管理计划) 知识点详解: 项目整体管理是项目管理知识体系的核心,它确保项目各要素协调统一。在考试中,特别要掌握项目章程和项目管理计划的区别与联系。 项目章程是项目的“出生证明”,由项目发起人发布。它正式授权项目,赋予项…...
SSE 基础知识
SSE 基础知识 一、概念定义 SSE 全称 Server-Sent Events,是基于HTTP协议的服务器单向数据推送技术。 建立一次长连接后,服务端可主动持续向前端推送数据,无需客户端反复轮询请求。 二、核心特点 单向通信:仅服务器 → 客户端发送…...
文件-语言-系统:基础IO-2.0——IO重定向接口,语言层缓冲区,系统级缓冲区。内核级分析!
bit::Shadow✧(≖ ◡ ≖✿ 目录 重定向接口dup2() ">" ">>" "<" 函数原型 输出重定向1和2的使用 文件描述符表 ./a.out运行: "./a.out >"默认重定向是fd 1 合并标准输入输出 缓冲区 什么是缓冲…...
AI算力要上天?别笑,太空数据中心真能干翻地球电费!
前言你有没有算过,训练一个大模型,相当于烧掉多少吨煤?如今AI狂飙突进,算力需求指数级增长,可地球上的电——不够用了!更别说建个数据中心还得跟地方政府“斗智斗勇”,抢地皮、配储能、扛审批&a…...
如何用WaveTools终极优化《鸣潮》游戏性能:从卡顿到丝滑的完整指南
如何用WaveTools终极优化《鸣潮》游戏性能:从卡顿到丝滑的完整指南 【免费下载链接】WaveTools 🧰鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 如果你正在玩《鸣潮》却频繁遭遇帧率波动、画面卡顿或操作延迟,那…...
OpenRASP原理与实战:Java应用层实时防护技术详解
1. 为什么我宁愿花三天部署OpenRASP,也不愿再写第五个自定义WAF过滤器去年冬天,我在给一家做在线教育SaaS平台做安全加固时,连续踩了三个坑:第一次用NginxLua写了套SQL注入规则,结果学生提交的“SELECT * FROM courses…...
java项目011-ssm 宠物医院系统
java项目011-ssm 宠物医院系统 是一款基于springspringmvcmybatis的宠物系统, 包含界面布局、医生信息管理、客户信息管理、宠物管理、浏览管理、 诊断管理、医生管理、用户管理 其中医生管理、用户管理只能管理员有权限进行操作。 采用spingboot方式启动 运行截图...
开源三角洲机器人Delta-Robot One:从入门到精通的创客实践指南
1. 项目概述:一个为学习而生的开源三角洲机器人如果你对机器人感兴趣,但又觉得它高深莫测、无从下手,那么Delta-Robot One(我们亲切地称它为“One”)可能就是为你量身打造的入门项目。这不是一个遥不可及的工业设备&am…...
告别Appium!用Python+UIAutomator2搞定Android自动化测试(附完整环境搭建与实战代码)
PythonUIAutomator2:Android自动化测试的高效实践指南 在移动应用测试领域,效率与稳定性始终是工程师们追求的核心目标。传统方案如Appium虽然功能全面,但在执行速度和资源消耗方面往往难以满足高频测试需求。本文将带您探索基于Python和UIA…...
UnityExplorer:如何在游戏运行时实时调试和修改Unity项目
UnityExplorer:如何在游戏运行时实时调试和修改Unity项目 【免费下载链接】UnityExplorer An in-game UI for exploring, debugging and modifying IL2CPP and Mono Unity games. 项目地址: https://gitcode.com/gh_mirrors/un/UnityExplorer UnityExplorer是…...
