一篇带你看懂异步: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…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
进程地址空间(比特课总结)
一、进程地址空间 1. 环境变量 1 )⽤户级环境变量与系统级环境变量 全局属性:环境变量具有全局属性,会被⼦进程继承。例如当bash启动⼦进程时,环 境变量会⾃动传递给⼦进程。 本地变量限制:本地变量只在当前进程(ba…...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
【力扣数据库知识手册笔记】索引
索引 索引的优缺点 优点1. 通过创建唯一性索引,可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度(创建索引的主要原因)。3. 可以加速表和表之间的连接,实现数据的参考完整性。4. 可以在查询过程中,…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
