Promise入门到精通(初级篇)-附代码详细讲解
Promise入门到精通(初级篇)-附代码详细讲解
Promise,中文翻译为承诺,约定,契约
,从字面意思来看,这应该是类似某种协议,规定了什么事件发生的条件和触发方法。
Promise的诞生和一个词有关,就是异步
什么是
异步???
首先javascript是运行在浏览器端的语言,必须依赖javascript引擎来解析并执行代码,js引擎是
单线程
,也就是一个任务接着一个任务来执行程序,这种单线程很容易因为一个任务发生延迟,造成整体的耗时变长,为了解决这个问题,所以就有了异步
这个概念。 异步就是当系统执行一个事件的时候,不会等待该事件结束,而是会去继续执行其他事件,当这个异步事件有了响应结果之后,系统会在空闲的时候继续执行该事件。
简单来说就是js引擎会首先判断该事件是同步任务还是异步任务,如果是同步任务,将该事件压入宏任务队列中排队等待执行,如果是异步事件,则进入微任务队列中等待宏任务队列处于空闲状态时,再将微任务队列中的事件移入宏任务队列执行。这样我们就可以把不确定执行时间的一些事件用异步来执行。提高了程序运行的效率,
Promise的核心概念
Promise中的核心概念是状态,状态转换就是Promise执行异步事件的时机
在Promise中有存在3种状态,分别对应的是:
1、等待(padding)
2、承诺实现(fulfilled)
3、承诺失效(reject)
Promise初始状态只能为等待的padding状态,在适当的时机,我们可以选择改变padding的状态到fulfilled或者reject。
️ Promise中的状态是不可逆转的,且仅允许改变一次,所以无法从fulfilled或reject状态再次切换到其他状态。当初始的padding改变为fulfilled或reject后,该Promise就相当于完成了它的使命,后续的异步处理就会交由一个then( )的方法来实现。
Promise的基本构成
在ES6语法中,Promise是一个构造函数
,使用时需要用new
关键词来创建实例对象。Promise构造函数中自带excutor
执行器,excutor执行器中有2个JavaScript中默认的函数参数resolve,reject
resolve函数的作用是当Promise状态从padding转换到resolve时,可以把Promise中的对象或者变量当成参数传递出来供异步成功时调用,reject函数的作用是当Promise状态从padding转换到reject时候可以把Promise中的对象或者变量,以及系统报错当成参数传递出来供异步失败时调用。
then是Promise原型上的一个方法,Promise.prototype.then()
所以通过构造函数创建的Promise实例对象也会自带then( )方法。then( )方法接受2个函数参数,作为Promise中异步成功和异步失败的2个回调函数。
Promise实例的基本代码结构:
//ES6 箭头函数写法
let promise = new Promise((resolve,reject)=>{
if(/判断条件/){
resolve()//承诺实现
}else{
reject()//承诺实效
}
})
promise.then(res=>{
//处理承诺实现方法
},err=>{
//处理承诺失效方法
})
️️️注意:Promise函数本身不是一个异步函数,在excutor执行器中运行的代码是同步的。执行异步的是then( )方法中的事件
console.log('步骤1');
new Promise((resolve,reject)=>{
console.log('步骤2');
})
console.log('步骤3')
//执行结果
### 步骤1
### 步骤2
### 步骤3
console.log('步骤1');
new Promise((resolve,reject)=>{
console.log('步骤2');
resolve()
}).then(res=>{
console.log('步骤3');
})
console.log('步骤4')
//执行结果
### 步骤1
### 步骤2
### 步骤4
### 步骤3
.catch也是Promise原型上的一个方法,用来接收和处理Promise中的异步失败,乍一看怎么和then( )中第二个函数参数的功能是一样的嘞?没错滴,这2种方法都是用来处理异步失败的回调函数,但它们2个之间还是有一些小小的区别。 then( )中第二个函数参数只能处理当前Promise异步失败的回调,而catch( )可以处理整个Promise链
上发生的异步失败的回调,便于异步失败和系统报错的整体处理。
let promise new Promise ((resolve,reject)=>{
reject('发生错误了')
})
promise.catch(err=>{
console.log(err)
})
//执行结果
### 发生错误了
let promise new Promise ((resolve,reject)=>{
throw ('发生错误了')
})
promise.catch(err=>{
console.log(err)
})
//执行结果
### 发生错误了
️ (推荐在Promise中使用catch来捕获处理异步失败方法和抛出错误)
Promise链式调用
链式调用是Promise中一个特别重要的属性。也是Promise能控制异步操作的关键,那么链式调用是什么?它的原理又是什么呢?
链式调用最重要的作用就是能使异步事件同步化
,将多个异步事件变为同步,
let promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve()
},100)
}).then(res=>{
console.log('我成功了');
})
let promise2 = new Promise((resolve,reject)=>{
resolve()
}).then(res=>{
console.log('我也成功了');
})
//执行结果
### 我也成功了
### 我成功了
可以看出,这两个方法执行顺序并不按照代码结构上的顺序来执行,也就是所谓的异步事件,
链式调用主要原理就是Promise.prototype.then方法和Promise.prototype.catch会返回一个新的Prmise对象,所以我们在Prmise后面可以一直使用then方法来处理异步事件,这样每个异步事件都会等上一个异步事件的then( )方法触发后才会执行自身,从而达到同步的效果.
当我们想让2个异步事件也遵循同步来执行就可以用Prmise的链式调用方法来重写代码结构:
let promise1 = new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve()
},100)
}).then(res=>{
console.log('我成功了');
return new Promise((resolve,reject)=>{
resolve()
})
}).then((res)=>{
console.log('我也成功了');
})
//执行结果
### 我成功了
### 我也成功了
Promise链式调用的规则
链式调用是Promise中一个重要的方法,能有效处理同步异步之间的逻辑关系,但是链式调用也有着自己一套使用规则,熟悉掌握它的规则才能更好的在开发中灵活的使用
规则1:Promise对象会默认返回一个新的Promise,当我们不手动进行干预的时候,这个返回的Promise对象状态为fulfilled
let promise = new Promise((resolve,reject)=>{
resolve()
}).then(res=>{
}).then(res=>{
console.log('规则1');
})
//上述的原理等价于下面的写法
Promise入门到精通(初级篇)-附代码详细讲解的更多相关文章
- YoloV4当中的Mosaic数据增强方法(附代码详细讲解)码农的后花园
上一期中讲解了图像分类和目标检测中的数据增强的区别和联系,这期讲解数据增强的进阶版- yolov4中的Mosaic数据增强方法以及CutMix. 前言 Yolov4的mosaic数据增强参考了CutM ...
- Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步
Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步 一.概述 PV操作是对信号量进行的操作. 进程同步是指在并发进程之间存在一种制约关系,一个进程的执行依赖另一个进程的消 ...
- SaltStack 入门到精通第二篇:Salt-master配置文件详解
SaltStack 入门到精通第二篇:Salt-master配置文件详解 转自(coocla):http://blog.coocla.org/301.html 原本想要重新翻译salt-mas ...
- SaltStack入门到精通第一篇:安装SaltStack
SaltStack入门到精通第一篇:安装SaltStack 作者:纳米龙 发布日期:2014-06-09 17:50:36 实际环境的设定: 系统环境: centos6 或centos5 实验机 ...
- Jmeter(三十四) - 从入门到精通进阶篇 - 参数化(详解教程)
1.简介 前边三十多篇文章主要介绍的是Jmeter的一些操作和基础知识,算是一些初级入门的知识点,从这一篇开始我们就来学习Jmeter比较高级的操作和深入的知识点了.今天这一篇主要是讲参数化,其实前边 ...
- Jmeter(三十五) - 从入门到精通进阶篇 - 关联(详解教程)
1.简介 上一篇中介绍了如果想要同时发送多条请求,那么怎样才能让每条数据某些请求参数改变呢.这就用到了jMeter参数化.在实际测试场景中,我们往往还有这样的需求,登录后服务器响应的token作为下次 ...
- Jmeter(三十八) - 从入门到精通进阶篇 - 命令行运行JMeter详解(详解教程)
1.简介 前边一篇文章介绍了如何生成测试报告,细心地小伙伴或者同学们可以看到宏哥启动Jmeter生成测试报告不是在gui页面操作的,而是在gui页面设置好保存以后,用命令行来生成测试报告的.这一篇宏哥 ...
- Jmeter(四十一) - 从入门到精通进阶篇 - Jmeter配置文件的刨根问底 - 下篇(详解教程)
1.简介 为什么宏哥要对Jmeter的配置文件进行一下讲解了,因为有的童鞋或者小伙伴在测试中遇到一些需要修改配置文件的问题不是很清楚也不是很懂,就算修改了也是模模糊糊的.更有甚者觉得那是禁地神圣不可轻 ...
- Jmeter(四十二) - 从入门到精通进阶篇 - Jmeter配置文件的刨根问底 -番外篇(详解教程)
1.简介 为什么宏哥要对Jmeter的配置文件进行一下讲解了,因为有的童鞋或者小伙伴在测试中遇到一些需要修改配置文件的问题不是很清楚也不是很懂,就算修改了也是模模糊糊的.更有甚者觉得那是禁地神圣不可轻 ...
随机推荐
- dm8数据库的安装 for linux
目录 dm8数据库的安装 for linux 1.创建用户 2.修改limit的文件 3.解压文件安装包 4.挂载iso镜像 5.对于安装介质和目录进行权限授予 6.切换用户安装数据库软件 7.dm数 ...
- 团队作业part5--测试与发布(Alpha版本)
测试报告 1.测试与解决bug 1)测试人员测试出的bug 游戏失败后方块还能下落 分数设计不太合理 存在行数不可消除的情况 2)开发人员解决bug 2.场景测试 适用群体:打发时间的学生.工作压力大 ...
- js之数组乱序
这是最近面试遇到的,不过忘记了,之前也有印象刷到过这道题,就再次记录一下加深印象吧,听到最多的答案是利用sort方法,不过也有说这种方法不好,利用了快排和插入排序,那就整理下吧 <!DOCTYP ...
- apidoc学习(接口文档定义取代word)
apidoc的安装,参考:https://blog.csdn.net/qq_36386771/article/details/82149848 生产文档,需要先编写一个apidoc.json对接口文档 ...
- logstash导入DNS解析数据到es中,中间有filebeat
这个过程中,主要用logstash处理数据的时候不好处理. 在logstash-sample.conf这个配置文件中的配置,我用这个监控filebeat的5044端口 # Sample Logstas ...
- SpringBoot集成Swagger2并配置多个包路径扫描
1. 简介 随着现在主流的前后端分离模式开发越来越成熟,接口文档的编写和规范是一件非常重要的事.简单的项目来说,对应的controller在一个包路径下,因此在Swagger配置参数时只需要配置一 ...
- Oracle 常用语句1
-- 我是注释信息 sql语句 -- 创建用户: create user 用户名 identified by 密码; create user jack identified by j123; -- l ...
- [OI笔记]杂题整理1(基础篇~)
算是开学第四周啦,之前的三周大概过了一遍基础图论和数学相关的内容.这篇随笔打算口胡一些近期做感觉比较好的数学相关的题目 因为这段时间主要是看紫书学的,所以其实会有些出自UVA的例题,如果需要题目但是觉 ...
- 简单的冒泡排序算法(java)
package lianxi; public class BubbleSort { public static void main(String[] args) { int[] array = {12 ...
- Kubernetes应用管理器OpenKruise之CloneSet
OpenKruise OpenKruise 是 Kubernetes 的一个标准扩展,它可以配合原生 Kubernetes 使用,并为管理应用容器.sidecar.镜像分发等方面提供更加强大和高效的能 ...