Promise-异步回调
1.理解Promise
promise是ES6提出的异步编程的新的解决方案,通过链式调用解决ajax回调地狱
从语法上看,promise是一个构造函数,自己身上有all、reject、resolve方法,原型上有then、catch方法
从功能上看,Promise对象用来封装一个异步请求操作并接受成功/失败时候的结果
2.Promise对象三种状态
promise对象中 PromiseState属性 ,这个属性有三种状态,分别是一下:
pending:等待中,或者进行中,还没有得到结果
resolved/fullfilled:执行成功
rejected:执行失败
这三种状态不受外界影响,而且状态只能从pending改变为resolved或者rejected,并且不可逆。
Promise对象的值
实例对象中的另外一个属性 PromiseResult
保存着异步任务【成功/失败】的结果,可以被resolve或者reject函数修改,修改后的结果可以被then函数接收到
then方法返回一个新的promise对象
①实例化一个Promise对象
②Promise作为一个构造函数,接受一个函数类型的值,这个函数有两个参数,分别是resolve reject
③当异步任务执行成功时候,调用resolve函数,将promise对象的状态修改为resolved,然后调用then方法中的第一个回调函数,并返回一个新的Promise对象
④当异步任务执行失败的时候,调用reject函数,将Promise对象的状态修改为rejected,然后调用then方法中的第二个回调函数,并返回一个新的Promise对象
3.Promise的基本使用
const promise = new Promise(function(resolve, reject) {// ... some codeif (/* 异步操作成功 */){resolve(value);} else {reject(reason);}
});
Promise作为一个构造函数,在实例化一个对象过程中,接受一个参数,这个参数是一个函数类型的值,这个函数里面有两个参数,分别是resolve、reject,当异步任务执行成功的时候,调用resolve函数,将promise对象的状态修改为resolved,并将异步操作的结果作为参数传递出去;异步任务执行失败的时候,调用reject函数,状态修改为rejected,并将异步操作的错误,作为参数reason传递出去
Promise实例 生成之后,可以调用then方法分别指定resolved状态和rejected状态的回调函数
then方法有两个参数,第一个参数是成功时候的回调,第二个参数是失败的时候的回调 接受构造函数中处理的状态的变化,并分别处理
promise.then(function(value) {// success
}, function(reason) {// failure
});
实例如下:
// 创建一个新的p对象promise
const p = new Promise((resolve, reject) => { // 执行器函数// 执行异步操作任务setTimeout(() => {const time = Date.now() // 如果当前时间是偶数代表成功,否则失败if (time % 2 == 0) {// 如果成功,调用resolve(value)resolve('成功的数据,time=' + time)} else {// 如果失败,调用reject(reason)reject('失败的数据,time=' + time)}}, 1000);
})p.then(value => { // 接收得到成功的value数据 onResolvedconsole.log('成功的回调', value) // 成功的回调 成功的数据,time=1615015043258},reason => { // 接收得到失败的reason数据 onRejectedconsole.log('失败的回调', reason) // 失败的回调 失败的数据,time=1615014995315}
)
Promise的封装AJAX请求
<script>function sendAJAX(url) {return new Promise((resolve, reject) => {const xhr = new XMLHttpRequest();//初始化xhr.open('GET', url)//发送数据xhr.send()xhr.responseType = 'json'xhr.onreadystatechange = function() {//响应已经完成,可以获取服务器响应了if (xhr.readyState === 4) {//状态码 2开头表示响应成功if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.response)} else {reject(xhr.status)}}}})}sendAJAX('https://api.vvhan.com/api/covid').then(value => {console.log(value);}, reason => {console.log(reason);})</script>
4. Promise的API
1.Promise构造函数:Promise(executor){}
executor函数:同步执行(resolve,reject)=>{}
resolve函数:内部定义成功时候调用的函数resolve(value)
reject函数:内部定义失败时候调用的函数reject(reason)
executor是执行器函数,会在Promise内部立即同步回调,异步操作resolve/reject就在executor中执行
2.Promise.prototype.then 方法:p.then(onResolved, onRejected)
onResolved 函数:成功的回调函数 (value) => {}
onRejected 函数:失败的回调函数 (reason) => {}
不管成功还是失败,都会返回一个新的Promise对象
3.Promise.prototype.catch 方法:p.catch(onRejected)
只能指定失败的回调
catch()相当于then(null,onRejected)
//console.dir(Promise)let p = new Promise((resolve, reject) => {// ** 同步调用console.log(111);//修改 promise 对象的状态// reject('error');});console.log(222);//执行 catch 方法// p.catch(reason => {// console.log(reason);// });
4.Promise.resolve方法:Promise.resolve(value)
value:将被Promise对象解析的参数,或者是一个成功/失败的Promise对象
返回:返回一个带着给定值解析过的 Promise 对象,如果参数本身就是一个 Promise 对象,则直接返回这个 Promise 对象。
如果resolve() 中的参数是非Promise对象,那么返回一个成功状态的Promise对象
如果resolve() 中的参数是Promise对象,那么返回的结果由这个Promise对象的返回结果决定
只有resolve()或者reject()函数才能改变PromiseResult的值,then()或者catch()能够接收到这个值
5.Promise.reject方法:Promise.reject(reason)
reason失败的原因,reject总是返回失败状态的Promise对象
总之,Promise.resolve()/Promise.reject() 用来快速得到Promise对象
//产生一个成功值为1的promise对象
new Promise((resolve, reject) => {resolve(1)
})
//相当于
const p1 = Promise.resolve(1)
const p2 = Promise.resolve(2)
const p3 = Promise.reject(3)p1.then(value => {console.log(value)}) // 1
p2.then(value => {console.log(value)}) // 2
p3.catch(reason => {console.log(reason)}) // 3
6.Promise.all方法:Promise.all()
参数是包含n个promise的数组
返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败了就直接失败
7.Promise.race方法:Promise.race()
参数是,包含n个promise对象的数组
返回一个新的promise对象,第一个完成的promise的状态结果就是最终的结果状态,总之,谁先完成就输出谁,不管他是成功or失败
5.promise中的重要问题
1.修改Promise对象状态的三种方法
1.resolve将promise对象状态:pending=>resolved/fullfilled
2.reject pending => rejected
3.throw 抛出一个异常 pending => rejected
2.Promise对象可以指定多个回调
3.改变promise对象的状态和指定回调函数的先后顺序
resolve()、reject()改变promise对象的状态,then/catch指定回调函数
执行器函数会在promise中同步回调,执行器函数中的resolve reject是异步操作
<script>//当执行器函数中的任务是一个同步任务,先改变状态后指定回调//当执行器函数中的任务一个异步任务时候,先指定回调后改变状态//执行器函数中一般都是异步任务, 添加定时器之后变成了异步任务let p = new Promise((resolve, reject) => {setTimeout(() => {resolve('OK');}, 1000);});p.then(value => {console.log(value);}, reason => {})</script>
如果先指定回调,会先保存当前指定的回调函数,当状态改变时(同时指定数据),执行回调函数
如果先改变状态(同时指定数据),后指定回调,直接执行回调函数
4.promise.then() 返回的新 promise 的结果状态由什么决定?
简述:由then()指定的回调函数执行的结果决定
详细:
①throw抛出一个异常,那么then返回的新promise对象的状态变为rejected,reason为抛出的异常
②回调函数的返回结果是一个非promise对象,新promise对象的状态变为resolved,value为返回的结果
③如果回调函数返回的结果是一个新promise对象,那么then函数返回的promise对象的结果同这个新promise对象的结果
5.promise如何串联多个操作任务
(1)promise 的 then() 返回一个新的 promise,可以并成 then() 的链式调用
(2)通过 then 的链式调用串联多个同步/异步任务
let p = new Promise((resolve, reject) => {setTimeout(() => {resolve('OK');}, 1000);
});p.then(value => {return new Promise((resolve, reject) => {resolve("success");});
}).then(value => {console.log(value); // success
}).then(value => {console.log(value); // undefined
})
6.promise异常穿透(传透)
所以失败的结果是一层一层处理下来的,最后传递到 catch 中。
或者,将 reason => {throw reason} 替换为 reason => Promise.reject(reason) 也是一样的
7.中断promise链
new Promise((resolve, reject) => {//resolve(1)reject(1)
}).then(value => {console.log('onResolved1()', value)return 2}
).then(value => {console.log('onResolved2()', value)return 3}
).then(value => {console.log('onResolved3()', value)}
).catch(reason => {console.log('onRejected1()', reason)return new Promise(() => {}) // 返回一个pending的promise}
).then(value => {console.log('onResolved4()', value)},reason => {console.log('onRejected2()', reason)}
)
// onRejected1() 1
在 catch 中返回一个新的 promise,且这个 promise 没有结果。
由于,返回的新的 promise 结果决定了后面 then 中的结果,所以后面的 then 中也没有结果。
这就实现了中断 promise链的效果。
参考
参考大佬的promise
尚硅谷 promise教程
相关文章:

Promise-异步回调
1.理解Promise promise是ES6提出的异步编程的新的解决方案,通过链式调用解决ajax回调地狱 从语法上看,promise是一个构造函数,自己身上有all、reject、resolve方法,原型上有then、catch方法 从功能上看,Promise对象用…...
【设计模式之美 设计原则与思想:设计原则】21 | 理论七:重复的代码就一定违背DRY吗?如何提高代码的复用性?
在上一节课中,我们讲了 KISS 原则和 YAGNI 原则,KISS 原则可以说是人尽皆知。今天,我们再学习一个你肯定听过的原则,那就是 DRY 原则。它的英文描述为:Don’t Repeat Yourself。中文直译为:不要重复自己。将…...

深度学习 | 入个Pytorch的小门
本文主要参考 1’ 2’ 3 更新:2023 / 3 / 1 深度学习 | 入个Pytorch的小门 - 1. 常见数据操作创建操作算术操作加法索引形状查询形状改变形状广播机制广播条件运算数据类型转换Tensor转NumPyNumPy转Tensor线性回归线性回归的基本要素1. 模型2. 数据集3. 损失函数4.…...
应用上云指导
应用上云指导方法论。应用上云指传统应用迁移到云上,云上应用采用K8S部署。本文旨在提供一种方法、流程,指导应用上云,以求优化上云工作,提供应用上云效率。主要包含以下内容:应用上云工作角色、分工应用上云标准流程及…...

进程概念~
进程概念 (冯诺依曼体系结构,操作系统,进程概念,进程状态,环境变量,程序地址空间) 冯诺依曼体系结构:(计算机硬件体系结构) 输入设备,输出设备&a…...

三天吃透Java基础八股文
本文已经收录到Github仓库,该仓库包含计算机基础、Java基础、多线程、JVM、数据库、Redis、Spring、Mybatis、SpringMVC、SpringBoot、分布式、微服务、设计模式、架构、校招社招分享等核心知识点,欢迎star~ Github地址:https://github.com/…...

YOLOv8训练自己的数据集(超详细)
一、准备深度学习环境本人的笔记本电脑系统是:Windows10YOLO系列最新版本的YOLOv8已经发布了,详细介绍可以参考我前面写的博客,目前ultralytics已经发布了部分代码以及说明,可以在github上下载YOLOv8代码,代码文件夹中…...
【洛谷 P1088】[NOIP2004 普及组] 火星人 题解(全排列+向量)
[NOIP2004 普及组] 火星人 题目描述 人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样的,首先,火星人把一个非常大的数字告诉人类科学…...
基于混合蛙跳算法优化SVM的滚动轴承故障诊断python实现
1.混合蛙跳算法(SFLA)原理 混合蛙跳算法(SFLA)是一种受自然生物模仿启示而产生的基于群体的协同搜索方法,由局部搜索和全局信息交换两部分组成。 混合蛙跳算法中,每个青蛙的位置代表了一个可行解。青蛙在沼泽中跳跃,沼泽在离散的地方有很多石头,青蛙可以跳过这些石头来找…...

如何让AI帮你干活-娱乐(2)
背景:好容易完成朋友的任务,帮忙给小朋友绘画比赛生成一些创意参考图片。他给我个挑战更高的问题,是否可以帮他用AI生成一些视频。这个乍一听以现在AI技术根本不太可能完成。奈何他各种坚持,无奈被迫营业。苦脸接受了这个不可能完…...

文件异步多备常用方案
业务需求上经常存在需要对同一个文件进行双上传,上传到不同云存储桶,以防出现某一个云厂商因各种意外导致自身服务出现不可用的情况,当然,还有其他措施可以避免,现在只针对通过程序业务代码而双写存储的这个场景。 业务…...

java面试八股文之------Redis夺命连环25问
java面试八股文之------Redis夺命连环25问👨🎓1.为什么redis这么快👨🎓2.redis的应用场景,为什么要用👨🎓3.redis6.0之前为什么一直不使用多线程,6.0为甚么又使用多线程了&…...

【数据结构】AVL平衡二叉树底层原理以及二叉树的演进之多叉树
1.AVL平衡二叉树底层原理 背景 二叉查找树左右子树极度不平衡,退化成为链表时候,相当于全表扫描,时间复杂度就变为了O(n) 插入速度没影响,但是查询速度变慢,比单链表都慢,每次都要判断左右子树是否为空 需…...
K8S篇-安装nfs插件
前言 有关k8s的搭建可以参考:http://t.csdn.cn/H84Zu 有关过程中使用到的nfs相关的nas,可以参考: http://t.csdn.cn/ACfoT http://t.csdn.cn/tPotK http://t.csdn.cn/JIn27 安装nfs存储插件 NFS-Subdir-External-Provisioner是一个自动配置…...

xmu 离散数学 卢杨班作业详解【4-7章】
文章目录第四章 二元关系和函数4.6.2911121618.120.222.1232834第五章 代数系统的一般概念2判断二元运算是否封闭348111214第六章 几个典型的代数系统1.5.6.7.11.12151618第七章 图的基本概念12479111215第四章 二元关系和函数 4. A{1,2,3} 恒等关系 IA{<1,1>,<2,2…...

多重背包问题中的二进制状态压缩
1.多重背包问题 经典的多重背包问题和01背包问题的相似之处在于二者的一维遍历顺序都是从右侧往左侧遍历。 同时多重背包的一维写法不比二维写法降低时间复杂度。 2.多重背包标准写法:(平铺展开形式) class Solution {public int maxValue(int N, int C, int[] s…...

汇编语言程序设计(四)之汇编指令
系列文章 汇编语言程序设计(一) 汇编语言程序设计(二)之寄存器 汇编语言程序设计(三)之汇编程序 汇编指令 1. 数据传输指令 指令包括:MOV、XCHG、XLAT、LEA、LDS、LES、PUSH、POP、PUSHF、LA…...

Vant2 源码分析之 vant-sticky
前言 原打算借鉴 vant-sticky 源码,实现业务需求的某个功能,第一眼看以为看懂了,拿来用的时候,才发现一知半解。看第二遍时,对不起,是我肤浅了。这里侧重分析实现原理,其他部分不拓展开来&…...

【自然语言处理】【大模型】大语言模型BLOOM推理工具测试
相关博客 【自然语言处理】【大模型】大语言模型BLOOM推理工具测试 【自然语言处理】【大模型】GLM-130B:一个开源双语预训练语言模型 【自然语言处理】【大模型】用于大型Transformer的8-bit矩阵乘法介绍 【自然语言处理】【大模型】BLOOM:一个176B参数…...

云桌面技术初识:VDI,IDV,VOI,RDS
VDI(Virtual Desktop Infrastucture,虚拟桌面架构),俗称虚拟云桌面 VDI构架采用的“集中存储、集中运算”构架,所有的桌面以虚拟机的方式运行在服务器硬件虚拟化层上,桌面以图像传输的方式发送到客户端。 …...

利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...

地震勘探——干扰波识别、井中地震时距曲线特点
目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波:可以用来解决所提出的地质任务的波;干扰波:所有妨碍辨认、追踪有效波的其他波。 地震勘探中,有效波和干扰波是相对的。例如,在反射波…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1
每日一言 生活的美好,总是藏在那些你咬牙坚持的日子里。 硬件:OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写,"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

【配置 YOLOX 用于按目录分类的图片数据集】
现在的图标点选越来越多,如何一步解决,采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集(每个目录代表一个类别,目录下是该类别的所有图片),你需要进行以下配置步骤&#x…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

springboot整合VUE之在线教育管理系统简介
可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生,小白用户,想学习知识的 有点基础,想要通过项…...
嵌入式常见 CPU 架构
架构类型架构厂商芯片厂商典型芯片特点与应用场景PICRISC (8/16 位)MicrochipMicrochipPIC16F877A、PIC18F4550简化指令集,单周期执行;低功耗、CIP 独立外设;用于家电、小电机控制、安防面板等嵌入式场景8051CISC (8 位)Intel(原始…...

【堆垛策略】设计方法
堆垛策略的设计是积木堆叠系统的核心,直接影响堆叠的稳定性、效率和容错能力。以下是分层次的堆垛策略设计方法,涵盖基础规则、优化算法和容错机制: 1. 基础堆垛规则 (1) 物理稳定性优先 重心原则: 大尺寸/重量积木在下…...