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。

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

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【云原生】详细学习Docker-Swarm部署搭建和基本使用

个人主页&#xff1a;征服bug-CSDN博客 kubernetes专栏&#xff1a;云原生_征服bug的博客-CSDN博客 目录 Docker-Swarm编排 1.概述 2.docker swarm优点 3.节点类型 4.服务和任务 5.路由网格 6.实践Docker swarm 1.概述 Docker Swarm 是 Docker 的集群管理工具。它将 Doc…

使用vue-grid-layout时 You may need an appropriate loader to handle this file type.

使用vue-grid-layout时 You may need an appropriate loader to handle this file type. node版本不匹配 我的node v14.16.0 vue-gride-layout 需要用 v 2.3.7的版本 卸载后重新安装即可

Swift async/await 并发中如何将任务组(TaskGroup)转换为异步序列(AsyncSequence)

功能需求 在 Swift 新结构化并行模型的开发中, 提出了任务组(TaskGroup)和异步序列(AsyncSequence)的概念。有时候,为了简洁和效率方面的原因,我们需要将 TaskGroup 的结果转换为异步序列。 如上图所示,我们试图将任务组的结果转换为异步序列,但不幸失败了。 那么…

GCC编译过程:预处理->编译->汇编->链接

目录 引言 概括介绍 一、预处理 二、编译 三、汇编 四、链接 总结 引言 当使用集成开发环境&#xff08;IDE&#xff09;进行C语言编程时&#xff0c;点击"编译"按钮后&#xff0c;整个C程序从源代码到可执行文件的生成过程会自动完成。IDE会在后台为我们执行C…

微服务——es数据聚合+RestClient实现聚合

数据聚合 聚合的种类 DSL实现Bucket聚合 如图所示&#xff0c;设置了10个桶&#xff0c;那么就显示了数量最多的前10个桶&#xff0c;品牌含有7天酒店的有30家&#xff0c; 品牌含有如家的也有30家。 修改排序规则 限定聚合范围 DSL实现Metrics聚合 如下案例要求对不同的品…

【Go 基础篇】Go语言初探:第一段代码与执行过程解析

介绍 Go语言&#xff08;也称为Golang&#xff09;作为一门现代化的编程语言&#xff0c;以其简洁的语法、高效的性能和丰富的标准库而受到了广泛关注和使用。对于初学者来说&#xff0c;编写和执行第一段Go代码是迈向这门语言的重要一步。本篇博客将带您深入了解Go语言的第一…

来讲一讲面试必问的异步FIFO设计!

异步FIFO设计可以说是数字IC设计工程师面试时必问的一个问题了&#xff0c;也是我们经常使用但是又往往被忽略的一个东西&#xff0c;今天就展开详细说一说不同深度&#xff08;2^N或者非2^N&#xff09;异步FIFO的设计思想&#xff1b; 一&#xff1a;2^N深度异步FIFO设计 1…

git和github学习

一、什么是git和github? 二、学会使用github desktop应用程序 初始使用&#xff1a; 一开始我们是新账户&#xff0c;里面是没有仓库的&#xff0c;需要手动创建一个仓库。此时&#xff0c;这个仓库是创建在本地仓库里面&#xff0c;需要用到push命令&#xff08;就是那个pub…

现代C++中的从头开始深度学习【2/8】:张量编程

一、说明 初学者文本&#xff1a;此文本需要入门级编程背景和对机器学习的基本了解。张量是在深度学习算法中表示数据的主要方式。它们广泛用于在算法执行期间实现输入、输出、参数和内部状态。 在这个故事中&#xff0c;我们将学习如何使用特征张量 API 来开发我们的C算法。具…

Android Studio实现简单ListView

效果图 MainActivity package com.example.listviewtest;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle; import android.widget.ListView;import com.example.listviewtest.adapter.PartAdapter; import com.example.listviewtest.bean.PartB…

【Spring Cloud 六】Hystrix熔断

这里写目录标题 系列文章目录背景一、Hystrix是什么服务雪崩服务容错的相关概念熔断器降级超时控制限流 二、会什么要有Hystrix三、如何使用Hystrix进行熔断处理整体项目代码服务提供者pom文件yml配置文件启动类controller 服务消费者pom文件yml配置文件启动类feignhystrixcont…

网络安全(黑客)零基础入门

导语 什么是 Web 安全&#xff1f;我又该如何入门学习它呢&#xff1f;学习过程中又应注意哪些问题呢&#xff1f;... 或许你的心中有着这样的疑问、不过别着急&#xff0c;本文会为你一一解答这些问题。 正文 定义 Web 安全&#xff0c;顾名思义便是由保障 Web 应用能够持续…

Windows新版文件资源管理器经常在后台弹出的临时解决方案

禁用组策略自动刷新 运行gpedit.msc找到计算机配置->管理模板->系统->组策略找到 “关闭组策略的后台刷新”启用 参考 https://answers.microsoft.com/en-us/windows/forum/all/windows-11-most-recently-opened-explorer-window/26e097bd-1eba-4462-99bd-61597b5…

【计算机网络】socket编程

文章目录 1. 网络通信的理解2.进程PID可以取代端口号吗&#xff1f;3. 认识TCP协议4. 认识 UDP协议5. socket编程接口udp_server.hpp的代码解析socket——创建 socket 文件描述符Initserver——初始化1.创建套接字接口&#xff0c;打开网络文件bind——绑定的使用 2.给服务器指…

鸿蒙智联再出发,携手伙伴共赢空间智能化,创造无限可能

新空间&#xff0c;再出发&#xff0c;HarmonyOS Connect伙伴峰会完 2023年8月5日&#xff0c;HarmonyOS Connect伙伴峰会在东莞如期举办&#xff0c;峰会以《一起创造无限可能 新空间 再出发》为主题&#xff0c;深度解读了鸿蒙智联商业模式全面升级以来&#xff0c;给伙伴带来…

Qt拖放事件与拖放操作笔记dragEnterEvent,dropEvent

1 介绍 拖放事件主要用于处理MIME数据&#xff0c;该数据是用于在发送电子邮件时&#xff0c;附加多媒体数据&#xff08;即拖拽一个文件放入邮件中&#xff0c;事件文件的上传&#xff09;。 2 示例 a&#xff09;使用简化步骤声明拖放事件成员函数&#xff1a; b&#xff09;…

C#与C/C++交互(1)——需要了解的基础知识

【前言】 C#中用于实现调用C/C的方案是P/Invoke&#xff08;Platform Invoke&#xff09;&#xff0c;让托管代码可以调用库中的函数。类似的功能&#xff0c;JAVA中叫JNI&#xff0c;Python中叫Ctypes。 常见的代码用法如下&#xff1a; [DllImport("Test.dll", E…

IPv6地址分类,EUI-64转换规则

1、可聚合的单全球单播地址Global Unique Address&#xff1a; Aggregate global unicast address&#xff0c;前3位是001&#xff0c;即2000::/3&#xff0c;目前IANA已经将一部分可聚合全球单播进行了专门使用&#xff0c;如&#xff1a;2001::/16用于IPV6互联网&#xff0c;…

流量分析日志查看

一流量分析 buuctf wireshark 从题目出发&#xff0c;既然是上传登录信息&#xff0c;就直接过滤post请求&#xff0c;即搜索 http.request.methodPOST&#xff0c;因为上传用户登录信息使用的一定是http里的post方法 模式过滤 http.request.method “GET” http.request.…

无涯教程-Perl - getpriority函数

描述 此函数返回进程(PRIO_PROCESS),进程组(PRIO_PGRP)或用户(PRIO_USER)的当前优先级。 参数WHICH指定要为PRIO_PROCESS,PRIO_PGRP或PRIO_USER之一设置优先级的实体,WHO是要设置的进程ID或用户ID。 WHO的值为0定义了当前流程,流程组或用户。这会在不支持系统getpriority()函…