Promise详细版

  • promise基础原理到难点分析

  • 常见的Promise的方法解读

  • 扩展async和await深入分析

  • 逐步分析Promise底层逻辑代码

一、Promise基础

1.什么是promise

为了解决回调地狱:

 //2.设置点击事件btn.onclick = function() {//3.创建ajax实例化对象let xhr = new XMLHttpRequest();//console.log('ajax实例化对象刚刚被创建出来:',xhr.readState)//4.打开请求xhr.open('get', 'http://iwewiki.com');//console.log('ajax已经打开了请求',xhr.readState)//5.发送请求(send方法中发送的是请求体数据,只不过get请求是没有请求体的,而post请求有请求体)xhr.send()//6.客户端接收服务端中响应回来的结果数据xhr.onreadystatechange = function() {// 2:已经完成了请求的发送// 3:响应结果途中还没有完全相应结果完毕...ing//4:已经完成了响应完毕结果了//console.log('0',xhr.readState)//7.判断if (xhr.readyState === 4) {//status:请求的状态码200-299之间if (xhr.status >= 200 && xhr.status < 300) {//8.获取请求数据(JSON字符串=>json对象)console.log(JSON.parse(xhr.responseText))}}}}

2.回调地狱

promise构造函数

 

then方法的返回值的Promise实例化对象的状态取决于回调函数中的内容

  • 如果返回为非Promise实例化对象,则得到一个是成功的Promise。

  

  • 如果返回的是promise实例化对象,则Promise实例化对象的状态和结构值将直接影响result常量的状态和结果值。

  •  如果为抛出异常,则新的Promise实例化对象(result)为失败的Promise

3.链式调用.then

对数据库进行操作: 

 

 封装一个函数来读取文件:

4.Promise.all()

Promise下的all方法作用主要是针对于多个Promise的异步任务的处理

需要接收一个数组类型的参数

返回值:Promise对象,状态也是由数组中的每一个Promise对象的状态来决定的

当所有的Promise对象的状态都是成功的,最终的结果就是成功的Promise,结果值是由每一个Promise的结果值组成的数组。

当所有的Promise对象的状态但凡有一个是失败的,最终也是失败的Promise,结果值就是失败的这个Promise的结果值

 

5.Promise.allSettled() 

 

allSettled方法用来确定一组异步地操作是否都结束了(不管是成功还是失败),其中包含了fulfilled和rejected两种情况

   <script>function ajax(url) {return new Promise((resolve, reject) => {let xhr = new XMLHttpRequest()xhr.open('get', url, true)xhr.send()xhr.onreadystatechange = function() {if (xhr.readyState === 4) {if (xhr.status >= 200 && xhr.status < 300) {resolve(xhr.responseText)} else {reject(xhr.responseText)}}}})}Promise.allSettled([ajax('地址1'), ajax('地址2')]).then(value => {let errorList = value.filter(item => item.status === 'rejected')console.log(errorList)}).catch(reason => {console.log(reason)})</script>

6.Promise.any()

有一个成功就是成功

Promise下的any方法,只要参数中有一个Promise实例化对象的状态为fulfilled,则整体结果就会为fulfilled。

如果所有Promise实力都是rejected,那么结果就是rejected

  <script>let p1 = new Promise((resolve, reject) => {resolve('ok');})let p2 = new Promise((resolve, reject) => {resolve('okk')})let result = Promise.any([p1, p2])console.log(result)</script>

 7.Promise.race()

 

Promise.race方法是需要传递一个参数,参数为数组,数组中的内容表示的是Promise实例化对象。

如果有最想到达状态的(pending来更改成fulfilled或者是rejected),不管是成功状态还是失败的状态,都将以这个对象的状态和结果值为准。

 8.Promise.reject()

 Promise.reject()方法将始终返回一个为失败的Promise对象,无论参数是否为Promise还是其他,最终都将返回失败的Promise

9.Promise.resolve()

 Promise下的resolve方法作用:将一个普通的值转换成Promise类型的数据.

分两种情况:

1.当resolve方法参数为非Promise对象,则返回的结果为成功的Promise对象

 

2.当resolve方法参数为Promise对象,则参数对象的状态和结果将直接影响最终resolve方法的返回值的那个对象的状态和结果

 10.catch

①then方法中是可以传入两个参数,当然也可以不传递,也可以只传递成功的回调函数

②也可以单独来使用catch来专门指定失败的回调函数

catch方法也有返回值,和then方法的返回值类似

catch方法也返回一个Promise实例化对象

情况1:如果失败回调函数中没有返回值,则得到一个成功的promise实例化对象,结构为undefined

情况2:如果失败回调函数中有返回值,但是这个返回值不是promise实例的情况下,则得到一个成功的promise实例化对象,结构为返回值数据

情况3:如果失败回电函数中有返回值,但是这个返回值是promise实例的情况下,则新的promise对象的状态和结果值完全取决于返回的Promise对象的状态以及结果值

 当然也可以和then方法结合使用

异常(错误)穿透

   当如果有多个需要执行的成功的回调,可以不每一次都写失败回调,可以一次性统一使用最后一次catch

   当Promise实例化对象的状态为rejected,则会一直向下穿透到catch方法

 11.finally

  finally是ES9中新增的特性,表示无论Promise对象变成了fulfilled还是rejected状态,最终都回执行finally方法的回调函数参数是不接受参数的。

12.终止promise链条

终止Promise链条主要就是为了返回 一个pending状态的Promise实例化对象。

 

13.async/await

使用async结合await的终极目标:就是同步的代码来完成异步的功能

1.async函数结合await表达式

   1.1async函数中不一定要完全结合await

    1.2有await的函数一定是async函数

2.await相当于then,可以直接拿到成功的Promise实例化对象的结果值

3.await一定要写在async函数之中,但是async函数之中可以没有await

4.如果await表达式后面是Promise实例化对象,则await返回的是Promise的成功的结果值

5.如果await表达式后面的其他值,则会直接将这个值作为await的返回值

 

 try....catch可以继续执行,并可以正常获取值

14.宏队列和微队列

JS中用来存储待执行回调函数的队列中包含了另个特定的队列

宏队列:用来保存执行的宏任务(回调),比如:定时器、DOM事件操作、ajax

微队列:用来保存执行的微任务(回调),比如:promise

JS执行的时候会区分两个队列

   --首先JS引擎会必须先将所有的同步代码都执行完

  ---每次准备取出第一个宏任务的执行之前,都需要将所有的微任务一个一个取出来执行

  ---顺序为   同--微--宏

二、手写Promise源码

Promise是一个构造函数,作用就是为了实例化对象。

语法:let 变量=new 构造函数名称();在堆内存中开辟一块空间,分配其大小以及设置其地址值0x100。

堆内存:主要存储的是引用数据类型的数据(数组、对象、函数)

栈内存:主要存储的是基本数据类型以及引用数据类型的地址值。

(一个函数如果作为另外一个方法的实际参数那么这么函数一定是回调函数)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/59860.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++/Qt读写ini文件

今天介绍C/Qt读写ini文件&#xff0c;ini文件一般是作为配置文件来使用&#xff0c;比如一些程序的一些默认参数会写在一个ini文件中&#xff0c;程序运行时会进行对应的参数读取&#xff0c;详细可以查看百度ini文件的介绍。https://baike.baidu.com/item/ini%E6%96%87%E4%BB%…

Spring Cloud Gateway

一 什么是Spring Cloud Gateway 网关作为流量的入口&#xff0c;常用的功能包括路由转发&#xff0c;权限校验&#xff0c;限流等。 Spring Cloud Gateway 是Spring Cloud官方推出的第二代网关框架&#xff0c;定位于取代 Netflix Zuul。相比 Zuul 来说&#xff0c;Spring Clo…

【导出Word】如何使用Java+Freemarker模板引擎,根据XML模板文件生成Word文档(只含文本内容的模板)

这篇文章&#xff0c;主要介绍如何使用JavaFreemarker模板引擎&#xff0c;根据XML模板文件生成Word文档。 目录 一、导出Word文档 1.1、基础知识 1.2、制作模板文件 1.3、代码实现 &#xff08;1&#xff09;引入依赖 &#xff08;2&#xff09;创建Freemarker工具类 &…

W5500-EVB-PICO作为TCP Client 进行数据回环测试(五)

前言 上一章我们用W5500-EVB-PICO开发板通过DNS解析www.baidu.com&#xff08;百度域名&#xff09;成功得到其IP地址&#xff0c;那么本章我们将用我们的开发板作为客户端去连接服务器&#xff0c;并做数据回环测试&#xff1a;收到服务器发送的数据&#xff0c;并回传给服务器…

【分布式系统】聊聊流量和数据调度

对于分布式系统来说&#xff0c;除了监控层面、以及服务治理层面&#xff0c;还有两个层面流量和数据调度。流量调度其实比较好理解&#xff0c;就是用户请求的流量&#xff0c;如何按照一定的策略算法打到不同的机器上。以及如何实现一个高可用、高性能的流量调度平台。而数据…

BM5 合并k个已排序的链表 javascript

描述 合并 k 个升序的链表并将结果作为一个升序的链表返回其头节点。 数据范围&#xff1a; 示例1 输入&#xff1a; [{1,2,3},{4,5,6,7}] 返回值&#xff1a; {1,2,3,4,5,6,7}示例2 输入&#xff1a; [{1,2},{1,4,5},{6}] 返回值&#xff1a; {1,1,2,4,5,6}解题思路 利用两个…

Electron学习1 安装环境与第一个程序

Electron学习1 安装环境与第一个程序 一、 Electron 简介二、安装 nvm三、安装nodejs四、安装nrm五、安装electron1. npm 初始化2. 创建 package.json3. 安装electron4. 创建一个页面5. 创建文件main.js6. 创建预加载器文件 preload.js7. 启动程序 六、打包 一、 Electron 简介…

Qt多线程编程

本章介绍Qt多线程编程。 1.方法 Qt多线程编程通常有2种方法&#xff1a; 1)通过继承QThread类&#xff0c;实现run()方法。 2)采用QObject::moveToThread()方法。 方法2是Qt官方推荐的方法&#xff0c;本文介绍第2种。 2.步骤 1)创建Worker类 这里的Worker类就是我们需要…

Nginx安装以及LVS-DR集群搭建

Nginx安装 1.环境准备 yum insatall -y make gcc gcc-c pcre-devel #pcre-devel -- pcre库 #安装openssl-devel yum install -y openssl-devel 2.tar安装包 3.解压软件包并创建软连接 tar -xf nginx-1.22.0.tar.gz -C /usr/local/ ln -s /usr/local/nginx-1.22.0/ /usr/local…

1999-2021年全国各地级市专利申请与获得情况、绿色专利申请与获得情况面板数据

1999-2021年全国各地级市专利申请与获得情况、绿色专利申请与获得情况面板数据 1、时间&#xff1a;2000-2021年 2、来源&#xff1a;国家知识产权局 3、范围&#xff1a;地级市&#xff08;具体每年地级市数量参看下文图片&#xff09; 4、指标&#xff1a;申请专利数&…

C语言---数据结构实验---哈夫曼树及哈夫曼编码的算法实现---图的基本操作

文章目录 写在前面哈夫曼树及哈夫曼编码的算法实现实验内容代码实现 图的基本操作实验内容代码实现 写在前面 本篇实验代码非本人写&#xff0c;代码源自外部&#xff0c;经调试解决了部分warning和error后在本地vs上可以正常运行&#xff0c;如有运行失败可换至vs 未来会重构…

【Leetcode】层次遍历||树深度||队列

step by step. 题目&#xff1a; 给定一个二叉树 root &#xff0c;返回其最大深度。 二叉树的 最大深度 是指从根节点到最远叶子节点的最长路径上的节点数。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;3示例 2&#xff1a; 输入&am…