【手写 Promise 源码】第三篇 - 实现一个简版 Promise

news2024/11/28 7:42:30

一,前言

上一篇,结合示例介绍了 Promise 相关功能与特性分析,包含以下内容:

  • Promise 基础特性;
  • Promise 实例 API(原型方法);
  • Promise 静态 API(类方法);
  • Promise 在不同场景下的特性分析;

本篇,根据之前对 Promise 的分析和了解,实现一个简版 Promise;


二,Promise 的实现思路

基于前面对 Promise 使用上的了解和分析,Promise 有以下几个关键特征:

  • Promise 是一个类;
  • 构造函数接收的参数是一个 excutor 函数;
  • 这个函数的参数是 resolve 和 reject 两个内部函数;
  • 构建 resolve 和 reject 并传入 excutor,并使之立即执行;
  • Promise 类有三种状态,默认为等待态;
  • 在 resolve 和 reject 中修改 status 状态;
  • Promise 类中包含 then 和 catch 等方法;

那么,一个 Promise 的结构如下:

class Promise () {
  constructor (fun) {
    this.status = 'pending'; // status:pending、fulfilled、rejected
    fun(this.resolve, this.reject); // 主体函数将会被立即执行
  }
  resolve() {}
  reject() {}
  then() {}
  catch() {}
}

三,Promise A+ 规范(简版)

上边的代码是根据理解“猜测”出来的,比较严谨的应该根据 Promise A+ 规范进行实现;

备注:本篇仅介绍 Promise A+ 规范中的基础部分,用于支撑实现简版 Promise;

1,技术点

image.png

  • 1.1 promise 是一个对象或函数,要有一个 then 方法,而且 then 方法需要符合规范;
  • 1.2 thenable 是一个对象或函数
  • 1.3 value 是一个合法的 js 值,可以是 undefined,一个 thenable 对象,或者是一个 promise 对象;
  • 1.4 异常可以使用 throw 代码块抛出
  • 1.5 reson 是一个值,它告诉我们 promise 为什么被拒绝了

简单分析:

  • promise有多种实现方式,可以是对象也可以是函数;符合标准即可;
  • 由于 promise 实例可以.then,所以我们认为 promise 实例是一个 thenable 对象;
  • 调用 reslove() 可以传值,不传就是 undefined,也可以传入 promise 或 thenable;

2,必要的

2.1 promise 状态

image.png

promise 有三个状态:pending等待态, fulfilled成功态 和 rejected失败态.

  • 2.1.1 当 promise 为 pending等待态 时,可以转换为fulfilled成功态 或 rejected失败态.
  • 2.1.2 当 promise 为 fulfilled成功态 时
    • 2.1.2.1 不能被转化为其他状态
    • 2.1.2.2 必须有一个值,且不能被改变
  • 2.1.3 当 promise 为 rejected失败态 时
    • 2.1.3.1 不能被转化为其他状态
    • 2.1.3.2 必须有一个原因,且不能被改变

2.2 then 是一个方法

image.png

一个 promise 必须有一个 then 方法,而且能够访问成功或失败的值;
一个 promise 能够接收两个参数,onFulfilled 和 onRejected;

。。。后面的内容暂时略过。。。

备注:了解至以上内容,足以支撑实现简版 Promise;

那么,可以基于以下 5 点,实现一个简版的 Promise:

1,promise 是一个类;
2, 使用 promise 时,传入 executor 执行器,并被立即执行;
3,executor 参数是两个函数,用于描述 promise 实例的状态;
resolve 表示成功,可以传入一个 value;
reject 表示失败,可以传入一个 reason;
4,每个 Promise 实例都有一个 then 方法;
5,promise 一旦状态发生后,不能再更改,
promise 有三种状态:成功态,失败态,等待态(默认)

四、实现简版 Promise

// 声明 promise 三种状态
const PENDING = 'PENDING';     // 等待态
const DULFILLED = 'DULFILLED'; // 成功态
const REJECTED = 'REJECTED';   // 失败态

class Promise{
  // 通过 new Promise 进行实例化时,传入 executor 执行器函数
  constructor(executor){

    this.value = undefined; // 保存成功的原因,then中调用onFulfilled时传入
    this.reason = undefined; // 保存失败的原因,then中调用onFulfilled时传入
    this.state = PENDING;   // promise 状态,默认等待态
    // 成功 reslove 函数、失败reject函数,并传入executor
    const reslove = (value) =>{
      // 等待态 --> 成功态
      if(this.state === PENDING){
        this.value = value
        this.state = DULFILLED;
      }
    }
    const reject = (reason) =>{
      // 等待态 --> 失败态
      if(this.state === PENDING){
        this.reason = reason
        this.state = REJECTED;
      }
    }
    
    // 立即执行 executor 执行器函数,通过 try...catch... 进行异常捕捉;
    try{
      executor(reslove, reject);
    }catch(e){
      reject(e)  // 有异常,调用 reject 更新为失败态
    }
  }
  
  // 定义 then 方法:包含两个参数 onFulfilled 和 onRejected;
  // 根据 Promise 状态,执行 onFulfilled 或 onRejected;
  then(onFulfilled, onRejected){
    // 成功态,调用 onFulfilled,传入成功 value
    if(this.state === DULFILLED){
      onFulfilled(this.value)
    } 
    // 失败态,执行 onRejected,传入失败 reason
    if(this.state === REJECTED){
      onRejected(this.reason)
    }
  }
}

// 导出 Promise 类供外部使用
module.exports = Promise; 

测试 promise 基础功能:

// 1,引入简版 Promise
let Promise = require('./source/promise');  

// 2.实例化 Promise 并传入 executor 执行器函数(会立即被执行)
let promise = new Promise((resolve, reject)=>{
  console.log('promise')
  throw new Error("抛出错误");
})

//  3,then 方法
promise.then((value)=>{
  console.log('success', value) 
},(reason)=>{
  console.log('err', reason)
})
console.log('ok')

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

这样,就完成了一个简版(示意版本)的 Promise;


五,结尾

本篇,根据对 Promise 的分析和了解,实现了一个简版 Promise,主要涉及以下内容:

  • Promise 的实现思路;
  • Promise A+ 规范(简版);
  • Promise 简版实现和功能测试;

下一篇,翻译并理解 Promise A+ 规范;


维护日志

  • 20211120:
    • 修改错别字

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

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

相关文章

【数据结构】极致详解:树与二叉树(中)——顺序存储实现

目录 📔前言📔: 📙一、顺序存储结构📙: 📘二、堆📘: 1.堆的概念及结构: 2.堆的性质: 3.堆的实现(本文重点)&#xf…

离线用户召回定时更新系列二

3.6.3 特征处理原则 离散数据 one-hot编码连续数据 归一化图片/文本 文章标签/关键词提取embedding3.6.4 优化训练方式 使用Batch SGD优化 加入正则化防止过拟合 3.6.5 spark LR 进行预估 目的:通过LR模型进行CTR预估步骤: 1、需要通过spark读取HIVE外…

Nacos学习笔记【part1】安装与注册服务

一、概述与安装 Nacos 是是一个构建云原生应用的动态服务发现、配置管理和服务管理平台,用于发现、配置和管理微服务,提供了一组简单易用的特性集,快速实现动态服务发现、服务配置、服务元数据及流量管理。 Nacos 更敏捷和容易地构建…

分享136个ASP源码,总有一款适合您

ASP源码 分享136个ASP源码,总有一款适合您 下面是文件的名字,我放了一些图片,文章里不是所有的图主要是放不下..., 136个ASP源码下载链接:https://pan.baidu.com/s/11db_K2QXns5pm8vMZBVPSw?pwds0lb 提取码&#x…

js 文字转语音 api SpeechSynthesisUtterance

SpeechSynthesisUtterance基本介绍 SpeechSynthesisUtterance是HTML5中新增的API,用于将指定文字合成为对应的语音.也包含一些配置项,指定如何去阅读(语言,音量,音调)等 官方文档地址(https://developer.mozilla.org/zh-CN/docs/Web/API/SpeechSynthesisUtterance…

【JavaEE初阶】第七节.多线程(基础篇)单例模式(案例一)

欢迎大家跟我一起来学习有关多线程的有关内容!!!!!!!!!! 文章目录 前言 一、单例模式的概念 二、单例模式的简单实 2.1 饿汉模式 2.2 懒汉模式 总结 前言…

搭建Linux环境

学习Linux之前,我们首先需要在电脑上搭建Linux操作系统环境。 就好比说你买了一台电脑,需要使用Windows10操作系统,那么首先应该安装Windows操作系统(刚买的电脑会引导你一步一步的安装)。 一、Linux环境搭建的三种方式…

数据结构 第三章 栈和队列(队列)

感谢:点击收听 1 基本知识点 1、允许删除的一端称为队头(front) 2、允许插入的一端称为队尾(rear) 3、当队列中没有元素时称为空队列 4、顺序队列: 1 使用顺序表来实现队列 2 两个指针分别指向队列的前端和尾端 **3 如果队列的大小为MaxSize个,那么元…

什么是倒排表(倒排索引)

这种搜索引擎的实现常常用的就是倒排的技术 文档(Document):一般搜索引擎的处理对象是互联网网页,而文档这个概念要更宽泛些,代表以文本形式存在的存储对象,相比网页来说,涵盖更多种形式,比如Word&#xff…

在Mac下如何创建文件

相比于windows中创建Mac是比较复杂的 第一步:打开启动台,依次打开「启动台-其他-自动操作」,可以按住「 Command 空格」直接搜索「自动操作」程序。 第二步:打开之后在「选取文稿类型」选项时,选择「快速操作」&#…

工地车辆未冲洗识别抓拍系统 yolov5网络

工地车辆未冲洗识别抓拍系统通过yolov5网络深度算法学习模型,自动对画面中每辆进出车辆的清洗实现自动识别判定。如果识别到车辆冲洗不合格,就会自动进行抓拍并将违规车辆信息回传。目标检测架构分为两种,一种是two-stage,一种是o…

「兔了个兔」看我如何抓取兔兔图片到本地(附源码)

💂作者简介: THUNDER王,一名热爱财税和SAP ABAP编程以及热爱分享的博主。目前于江西师范大学会计学专业大二本科在读,同时任汉硕云(广东)科技有限公司ABAP开发顾问。在学习工作中,我通常使用偏后…

如何在IDEA中使用Maven构建Java项目?Maven的使用详细解读

文章目录1. 前言2. IDEA 中配置 Maven 环境3. Maven 的坐标问题4. IDEA 中创建 Maven 项目5. IDEA 中导入 Maven 项目6. 安装插件7. 依赖管理8. 依赖范围6. 总结Java编程基础教程系列1. 前言 前面在如何使用 Maven 构建 Java 项目一文中,我们一直在命令行中执行构建…

LabVIEW什么是实时操作系统(RTOS)

LabVIEW什么是实时操作系统(RTOS)一般而言,操作系统的任务是管理计算机的硬件资源和应用程序。实时操作系统会执行这些任务,但是运行时间精度和可靠度都极高。在实际应用中,有的系统失常代价高昂,甚至会引起安全事故。这时&#x…

成为提示专家,AI艺术杂志:AI Unleashed 第一期

shadow最近发现了一期AI艺术的杂志。名称叫 AI Unleashed,是一本深入探索 AI 和想象力的杂志。每期杂志都将填满精彩的 AI 艺术,激发你的好奇心, 让你更加了解最新的 AI 技术,以及它如何改变现有工作流和我们对艺术和技术的看法。…

LVS+keepalived(双主)+Nginx实现高可用负载均衡

#为什么采用双主架构: 单主架构只有一个keepalived对外提供服务,该主机长期处于繁忙状态,而另一台主机却很空闲,利用率低下 #双主架构的优点: 即将两个或以上VIP分别运行在不同的keepalived服务器,以实现…

C++11使用线程类thread的方法

C11 之前,C 语言没有对并发编程提供语言级别的支持。如果需要使用线程,windows系统需要使用CreateThread函数创建线程,而linux需要使用pthread库使用线程。C11 中增加了线程以及线程相关的类,很方便地支持了并发编程。由于可以跨平…

活动星投票十大商业品牌网络评选微信的投票方式线上免费投票

“十大商业品牌”网络评选投票_线上系统免费投票_功能齐全的视频投票_在线投票免费小程序用户在使用微信投票的时候,需要功能齐全,又快捷方便的投票小程序。而“活动星投票”这款软件使用非常的方便,用户可以随时使用手机微信小程序获得线上投…

CV学习笔记-VGG

VGG 1. 常见的卷积神经网络 VGG属于一种经典的卷积神经网络结构,其出现在AlexNet之后,由于AlexNet的突破证实了卷积神经网络的可行性,VGG的思路主要是将网络层数加深,从某种意义上说,网络层数的加深可以粗略地认为考虑…

编译原理学习笔记14——属性文法与语法制导翻译1

编译原理学习笔记14——属性文法与语法制导翻译114.1 属性文法14.2 属性计算14.1 属性文法 属性文法 综合属性 自下而上传递信息语法规则:根据右 部候选式中的符号 的属性计算左部被 定义符号的综合属性语法树:根据子结 点的属性和父结点 自身的属性…