【手写 Promise 源码】第二篇 - Promise 功能介绍与特性分析

news2025/1/12 8:53:34

一,前言

上一篇,对 Promise 进行了简单介绍,主要涉及以下几个点:

  • Promise 简介和基本使用;
  • Promise 和 callback 对比;
  • Promise 的重要性和作用;
  • Promise 使用场景:Promisify 封装;
  • Promise 的优缺点、兼容性;

本篇,将结合示例对 Promise 进行相关功能介绍与特性分析;

备注:

  • 本篇持续更新,争取覆盖 Promise 大多数基础功能和特性;
  • 较为复杂的面试题部分,会在专栏最后集中进行梳理和总结;

二,Promise 基础特性

1,Promise 类

image.png

  • Promise 能够通过 new 进行对象创建,说明它是一个类或或构造函数;
  • 使用 Promise 时,需要传入一个 executor 执行器;
  • executor 执行器的入参包含 reslove 和 reject 两个函数;
  • 引出了 executor 执行器;
  • 引出了 reslove 和 reject;

2,executor 执行器

代码示例:

new Promise(()=>{ // executor 执行器
  console.log('promise')
})
console.log('ok')

// 执行结果:
promise
ok
  • 现象:先输出 promise,后输出 ok;
  • 所以,executor 执行器会在 Promise 创建完成后被立即执行
  • 介绍了 executor 执行器;会在 Promise 创建后被立即执行;

3,Promise 的三种状态

Promise 具有三种状态:

  • pending:等待态(默认);
  • fulfilled:成功态;
  • rejected:失败态;

代码示例:

let promise = new Promise(()=>{
  console.log('promise')
})
console.log('ok', promise)

// 执行结果:
promise
ok Promise { <pending> }
  • Promise 状态默认为 pending 等待态:
  • Promise 状态可以通过调用 reslove 或 reject 改变(仅能够被改变一次);
  • 介绍了 Promise 的三种状态;
  • 引出了 reslove、reject 与 Promise状态的关系;

4,reslove 和 reject 的作用

executor 执行器的两个函数 reslove 和 reject,用于描述 Promise 状态:

  • 当异步操作成功时,通过调用 resolve 返回异步操作的成功结果;
  • 当异步操作失败时,通过调用 reject 返回异步操作的失败结果;

reslove

  • 通过调用 reslove 函数,使当前 Promise 状态变更为成功态 fulfilled;
  • resolve 表示成功,可以传入一个 value;

示例:

let promise = new Promise((resolve, reject)=>{
  console.log('promise')
  resolve("成功");	// 调用 resolve 方法
})
console.log('ok', promise)

// 执行结果:
promise
ok Promise { '成功' }

reject

  • 通过调用 reject 函数,使当前 Promise 状态变更为失败态 rejected;
  • reject 表示失败,可以传入一个 reason;

实例:

let promise = new Promise((resolve, reject)=>{
  console.log('promise')
  reject("失败");	// 调用 reject 方法
})
console.log('ok', promise)

// 执行结果:
promise
ok Promise { <rejected> '失败' }
  • 介绍了 reslove 和 reject 的使用方式:调用和传参;
  • 介绍了 reslove、reject 与 Promise 状态的对应关系;

5,Promise 实例的状态只能改变一次

代码示例:

let promise = new Promise((resolve, reject)=>{
  console.log('promise')
  throw new Error("抛出错误");
  resolve();  // 已经失败了,再调用resolve成功,状态不会发生变化
})
promise.then((value)=>{
  console.log('success', value) 
},(reson)=>{
  console.log('err',reson)
})
console.log('ok')

// 执行结果:
promise
ok
err Error: 抛出错误

Promise 实例的状态一旦发生变化,不能再次被更改:

  • promise 状态只能从 pending 更新为 fulfilled 成功态,或是从 pending 更新为 rejected 失败态;
  • 当 promise 为成功或失败状态时,不能再次通过调用 resolve、reject或抛出异常来改变 当前 promise 实例的状态;

示例中使用到了 promise.then() ,将会在下边进行详细介绍;

6,Promise API

与绝大多数的“class 类”相似,Promise API 也分为以下两大类:

  • 实例 API 或原型方法:必须要 new 出实例才能使用的实例方法;
  • 静态 API 或类方法:不需要 new 出实例就可以使用的静态方法;

其中,分别包含了以下方法:

  • Promise 共有 3 个实例方法:thencatchfinally
  • Promise 共有 4 个静态方法:resolverejectallrace

三,Promise 实例 API(原型方法)

Promise 共有 4 个实例方法,分别是:thencatchfinally

1,Promise.prototype.then()

功能介绍

image.png

  • 每个 Promise 实例都有一个 then 方法;
  • Promise 对异步操作执行结果的处理:
    • 通过调用 resolve 使状态更新为成功态,进入 then 成功回调处理;
    • 通过调用 reject 使状态更新为失败态,进入 then 失败回调处理;
  • then 方法的两个参数(onFulfilled 和 onRejected):
    • 第一个参数:onFulfilled 成功的回调:成功状态时被调用;
    • 第二个参数:onRejected 失败的回调:失败状态时被调用;

代码示例

// promise 有三种状态:成功态,失败态,等待态(默认)
// 调用 resolve,状态更新为成功态,进入 then 成功回调;
// 调用 reject,状态更新为失败态,进入 then 失败回调;
// 每个 promise 实例的状态只能给改变一次;
let promise = new Promise((resolve, reject)=>{
  console.log('promise')
  resolve("成功");     // 进入 then 成功处理
  // reject("失败");   // 进入 then 失败处理
  // throw new Error("发生错误"); // 进入 then 失败处理
})

promise.then((value)=>{
  console.log('success', value) // onFulfilled:成功状态时被调用
},()=>{
  console.log('err')     // onRejected:失败状态时被调用 
})

console.log('ok')

// 执行结果:
promise      -> executor 被立即执行
ok           -> 直接执行完毕,then 方法为异步
success 成功 -> promise 异步处理完成,进入 then 中 onFulfilled 函数
  • 从控制台输出可以看出:promise 实例创建后 executor 被立即执行,但是 then 方法却是异步执行的;

备注:

  • 调用 resolve 会进入成功处理;
  • 调用 reject 或发生异常会进入失败处理;
  • 若在 Promise 中既没有调用 resolve 也没有调用 reject,此时的 Promise 默认为等待态;将不会进入成功或失败的回调,即不会进入 then 方法处理;

进入条件

Promise 主体任务此前链式调用中的全部回调任务都成功时(即通过 resolve 标注状态),进入本次 then() 回调;

2,Promise.prototype.catch()

功能介绍

image.png

Promise.prototype.catch()方法就是 .then(null, rejection).then(undefined, rejection)的别名, 用于指定发生错误时的回调函数;

代码示例

进入条件

Promise 主体任务此前链式调用中出现异常且未被捕获时(即通过 reject 标注状态或出现 JS 原生报错且没有被处理时),进入本次 catch()回调;

3,Promise.prototype.finally()

功能介绍

代码示例

进入条件

无论链式调用过程中是否出现成功或者失败,最终都将会执行 finally 方法,除非没有添加 .finally 处理;

四,Promise 静态 API(类方法)

Promise 共有 4 个静态方法,分别是:resolverejectallrace

1,Promise.resolve()

功能介绍

  • Promise.resolve():创建并返回一个成功状态的 Promise 实例;
  • 常用于构建微任务;(构建宏任务常用setTimeout);

代码示例

以下示例并没问题,但却是一个冗余的 Promise 封装:

// 冗余的 Promise 封装
function getData() {
  return new Promise((resolve) => {
    const a = 1;
    const b = 2;
    const c = a + b;
    resolve(c);
  })
}

这种情况,可以直接使用 Promise.resolve 快速创建一个成功状态的 Promise 对象,构建成为一个微任务:

function getData() {
  const a = 1;
  const b = 2;
  const c = a + b;
  return Promise.resolve(c); // 创建成功状态 promise 实例,放入微任务队列
}

2,Promise.reject()

功能介绍

  • Promise.reject():创建并返回一个失败状态的 Promise 实例;

代码示例

3,Promise.all()

功能介绍

代码示例

4,Promise.race()

功能介绍

代码示例


五,结尾

本篇,主要通过示例对 Promise 进行了相关功能的介绍与特性分析,主要涉及以下几个点:

  • Promise 的基础特性;
  • Promise 实例 API(原型方法)的介绍和使用;
  • Promise 静态 API(类方法)的介绍和使用;

下一篇,介绍 Promise A+ 规范,后续会从 0 ~ 1 实现一个 Promise;


维护日志

  • 20211025
    • 重新梳理文章大纲,整理目录,扩充相关内容;
    • 更新文章摘要;
  • 20211103
    • 修改错别字;
  • 20211120
    • 修改结尾部分,修改文章摘要;

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

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

相关文章

Python Flask 框架设置响应头,一篇文章学明白

flask 响应头设置&#x1f4d6; 导读&#x1f4d6; Python Flask 设置响应头&#x1f389; response.headers 属性&#x1f389; flask.abort() 函数返回特定状态码&#x1f4d6; Flask 中可设置的响应头参数&#x1f4d6; 其他关于响应头的配置&#x1f381; 使用中间件&#…

[Python]调用pytdx的代码示例

安装pytdxpip install pytdx简单示范from pytdx.hq import TdxHq_API api TdxHq_API() # 数据获取接口一般返回list结构&#xff0c; with api.connect(119.147.212.81, 7709): # 返回普通listdata api.get_security_bars(9, 0, 000001, 0, 10) print(data)输出结果[Ordered…

康巴丝(compas)某Wi-Fi万年历无法自动校时的问题

笔者前两年购买过一块康巴丝牌的电子万年历&#xff0c;该万年历的最大特点可以通过Wi-Fi联网自动校时。 后来的某一天&#xff0c;笔者将原来的H3C AP&#xff08;11AC&#xff09;升级为锐捷AP&#xff08;11AX&#xff09;。 在之后的几个月中&#xff0c;发现这块电子万年…

Linux常用命令——setsebool命令

在线Linux命令查询工具(http://www.lzltool.com/LinuxCommand) setsebool 修改SElinux策略内各项规则的布尔值 补充说明 setsebool命令是用来修改SElinux策略内各项规则的布尔值。setsebool命令和getsebool命令是SELinux修改和查询布尔值的一套工具组。SELinux的策略与规则…

【云原生】Prometheus 监控系统的初步了解与系统搭建

内容预知 前言 1. Prometheus的相关知识 1.1 Prometheus的认识与了解 1.2 Prometheus的特点 1.3 Prometheus存储引擎TSDB 的特点优势 1.4 Prometheus 的生态组件 &#xff08;1&#xff09;Prometheus server &#xff08;2&#xff09;Client Library &#xff08;3&a…

主流的操作系统(带你快速了解)

&#x1f4dc; “作者 久绊A” 专注记录自己所整理的Java、web、sql等&#xff0c;IT技术干货、学习经验、面试资料、刷题记录&#xff0c;以及遇到的问题和解决方案&#xff0c;记录自己成长的点滴。 &#x1f341; 操作系统【带你快速了解】对于电脑来说&#xff0c;如果说…

如何安装双系统与多系统(带你快速了解)

&#x1f4dc; “作者 久绊A” 专注记录自己所整理的Java、web、sql等&#xff0c;IT技术干货、学习经验、面试资料、刷题记录&#xff0c;以及遇到的问题和解决方案&#xff0c;记录自己成长的点滴。 &#x1f341; 操作系统【带你快速了解】对于电脑来说&#xff0c;如果说…

开放式基金净值历史数据 API 数据接口

开放式基金净值历史数据 API 数据接口 实时净值&#xff0c;历史数据&#xff0c;多维度指数参数。 1. 产品功能 支持所有开放式基金净值历史数据查询&#xff1b;可定义查询指标与时间范围&#xff1b;支持所有开放式基金净值历史数据查询&#xff1b;不同的输入指标返回不同…

java-List

java-List1. 预备知识-泛型(Generic)1.1 泛型的引入1.2 泛型的分类1.3 泛型类的定义的简单演示1.4 泛型背后作用时期和背后的简单原理1.5 泛型类的使用1.6 泛型总结2. 预备知识-包装类(Wrapper Class)2.1 基本数据类型和包装类直接的对应关系2.2 包装类的使用&#xff0c;装箱(…

Windows压缩工具 “ Bandizip与7-zip ”(带你快速了解)

&#x1f4dc; “作者 久绊A” 专注记录自己所整理的Java、web、sql等&#xff0c;IT技术干货、学习经验、面试资料、刷题记录&#xff0c;以及遇到的问题和解决方案&#xff0c;记录自己成长的点滴。 &#x1f341; 操作系统【带你快速了解】对于电脑来说&#xff0c;如果说…

机器视觉在烟草领域中的应用

一个不知名大学生&#xff0c;江湖人称菜狗 original author: jacky Li Email : 3435673055qq.com Time of completion&#xff1a;2023.1.26 Last edited: 2023.1.26 目录 机器视觉在烟草领域中的应用 烟叶外观检测 烟末原料异物检测 叶梗烟丝缺陷检测 香烟过滤嘴外型检测…

(21)go-micro微服务logstash使用

文章目录一 Logstash介绍二 Logstash作用三 Logstash工作原理四 Logstash安装1.拉取镜像2.运行命令3.查看是否运行五 Logstash使用六 最后一 Logstash介绍 Logstash是具有实时流水线能力的开源的数据收集引擎。Logstash可以动态统一不同来源的数据&#xff0c;并将数据标准化到…

活动星投票自控好声音网络评选微信的投票方式线上免费投票

“自控好声音”网络评选投票_投票平台的陆续发展_小程序投票的好处与坏处_如何进行有效的图文投票近些年来&#xff0c;第三方的微信投票制作平台如雨后春笋般络绎不绝。随着手机的互联网的发展及微信开放平台各项基于手机能力的开放&#xff0c;更多人选择微信投票小程序平台&…

恶意代码分析实战 17 C++代码分析

17.1 Lab20-01 问题 在0x401040处的函数采用了什么参数&#xff1f; 首先&#xff0c;以①处的一个对new操作符的调用开始&#xff0c;这表明它正在创建一个对象。一个对象的引用会在EAX寄存器中返回最终存储在②处的var_8变量和③处的var_4变量中。var_4变量在④处被移到了E…

pytorch深度学习基础(十)——常用线性CNN模型的结构与训练

线性CNN模型的结构与训练引入包LeNet模型结构模型构建AlexNet模型结构模型构建VGG模型结构模型构建加载数据集累加器精度训练引入包 import torch from torch import nn from torchvision import datasets from torchvision import transforms from torch.utils.data import D…

基于蜣螂算法的极限学习机(ELM)分类算法-附代码

基于蜣螂算法的极限学习机(ELM)分类算法 文章目录基于蜣螂算法的极限学习机(ELM)分类算法1.极限学习机原理概述2.ELM学习算法3.分类问题4.基于蜣螂算法优化的ELM5.测试结果6.参考文献7.Matlab代码摘要&#xff1a;本文利用蜣螂算法对极限学习机进行优化&#xff0c;并用于分类问…

【华为上机真题】连续字母长度

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

C语言--指针初阶

目录什么是指针&#xff1f;指针变量指针类型指针类型的意义在数组中举例野指针概念野指针成因如何规避野指针指针运算指针-整数指针关系运算指针-指针应用(求字符串长度)结语什么是指针&#xff1f; 在计算机科学中&#xff0c;指针&#xff08;Pointer&#xff09;是编程语言…

直接在Notepad++中运行GO

1.Windows上安装Go语言开发包参考链接&#xff1a;http://c.biancheng.net/view/3992.html1.1.下载Go语言开发包可以在Go语言官网 &#xff08;https://golang.google.cn/dl/&#xff09; 下载Windows 系统下的Go语言开发包&#xff0c;如下图所示。这里我们下载的是64 位的开发…

深度学习:轻量级神经网络MobileNet 从v1 到v2

深度学习&#xff1a;轻量级神经网络MoblieNet 从v1 到 v2MobileNet V1前言深度可分离卷积传统卷积Depth Wise ConvPoint Wise Conv性能对比MobileNet V2前言主要改进Inverted Residuals BlockResidual BlockExpansion LayerReLU6Linear Activation Function小结实验MobileNet …