手写Promise实现

手写Promise实现

  • 一、前言
  • 二、代码
  • 三、测试
  • 四、测试结果

一、前言

  阅读参考资料,本文整理出使用 构造函数 手撕出 Promise 的方法,在整理过程中不断添加注解以示思路。有错请指出哟,一起进步!!!class 实现 Promise 请查看参考资料,该作者写得非常好、非常详细!!!
  参考资料:promise原理手写实现promise以及async await

二、代码

// 构造函数
function MyPromise(executor) {
  // 添加属性
  this.PromiseState = 'pending'
  this.PromiseResult = null
  // 保存实例对象的this
  const self = this
  // 声明属性
  // this.callbacks = {}
  this.callbacks = []
  
  function resolve(data){
    // 判断状态
	// 普通函数的this一般指window对象
	// 错误写法:直接this.PromiseState !== 'pending'
    if(self.PromiseState !== 'pending')return
    // 修改对象状态
    self.PromiseState = 'fulfilled'
    // 设置对象结果
    self.PromiseResult = data
    // 调用回调函数
    // if(self.callbacks.onFulfilled) {
    //   onFulfilled(data)
    // }
	setTimeout(() => {
	  self.callbacks.forEach(item => {
        item.onFulfilled(data)
      })
	})
  }
  function reject(reason) {
    if(self.PromiseState !== 'pending')return
    self.PromiseState = 'rejected'
    self.PromiseResult = reason
	// js执行顺序:同步任务 > Promise.then() > setTimeout() 
	setTimeout(() => {
	  self.callbacks.forEach(item => {
        item.onRejected(reason)
      })
	}) 
  }
  try {
	// executor是一个函数,resolve函数和reject函数作为参数传递
	// 生成Promise实例时就执行
    executor(resolve, reject)
  } catch(e) {
    reject(e)
  }
}

// 添加then方法
// then方法返回的是一个Promise对象,方便链式调用
MyPromise.prototype.then = function(onFulfilled, onRejected) {
  // 要将实例的this保存下来,普通函数的this指向window对象
  const self = this
  // 判断回调函数参数
  if(typeof onRejected !== 'function') {
    onRejected = reason => {
      throw reason
    }
  }
  if(typeof onFulfilled !== 'function') {
    onFulfilled = data => data
  }
  return new MyPromise((resolve, reject) => {
    // 封装回调函数
    function callback(type) {
      try {
		// 获取回调函数的结果
        let result = type(self.PromiseResult)
        if(result instanceof MyPromise) {
          result.then(data => {
            resolve(data)
          }, reason => {
            reject(reason)
          })
        } else {
          resolve(result)
        }
      } catch(e) {
        reject(e)
      } 
    }
    if(this.PromiseState === 'fulfilled') {
      callback(onFulfilled)
    }
    if(this.PromiseState === 'rejected') {
      callback(onRejected)
    }
	if(this.PromiseState === 'pending') {
      this.callbacks.push({
        onFulfilled: function() {
          callback(onFulfilled)
        },
        onRejected: function() {
          callback(onRejected)
        }
      })
    }
  })
}

// 添加catch方法
// 1、当使用 promise 的 then 链式调用时, 可以在最后指定失败的回调
// 2、前面任何操作出了异常, 都会传到最后失败的回调中处理
MyPromise.prototype.catch = function(onRejected) {
  return this.then(undefined, onRejected)
}

// 添加resolve静态方法
// 静态方法直接绑定到构造函数上,而不是绑定到实例对象上。
// 只能通过构造函数本身调用,实例对象不能调用
MyPromise.resolve = function(data) {
  // 返回Promise对象
  return new MyPromise((resolve, reject) => {
    if(data instanceof MyPromise) {
      data.then(data => {
        resolve(data)
      }, reason => {
        reject(reason)
      })
    } else {
      resolve(data)
    }
  })
}

// 添加reject方法
MyPromise.reject = function(reason) {
  return new MyPromise((resolve, reject) => {
    reject(reason)
  })
}

// 添加all方法
MyPromise.all = function(promises) {
  // promises是n个Promise对象
  // 结果返回一个新的 promise,只有所有的 promise 都成功才成功,只要有一个失败了就直接失败
  return new MyPromise((resolve, reject) => {
	let count = 0
	let arr = []
	for(let i = 0; i < promises.length; i++) {
	  promises[i].then(data => {
		count++
		arr[i] = data
		// 关键:判断是否所有promises都成功
		if(count === promises.length) {
		  resolve(arr)
		}
	  }, reason => {
		reject(reason)
	  })
	}
  })	
}

// 添加race方法
MyPromise.race = function(promises) {
  // 返回一个新的 promise
  // 第一个完成的 promise 的结果状态就是最终的结果状态,谁先完成就输出谁(不管是成功还是失败)
  return new MyPromise((resolve, reject) => {
	for(let i = 0; i < promises.length; i++) {
	  promises[i].then(data => {
		resolve(data)
	  }, reason => {
		reject(reason) 
	  })
	}
  })
}

三、测试

// Promise链式调用:链式调用意味着你可以在一个Promise完成后,用then方法链式调用另一个Promise。
const p = new MyPromise((resolve, reject) => {
  resolve('resolved')
}).then(data => {
  return new MyPromise((resolve, reject) => {
	resolve('resolved again')
  })
}).then(data=>{
  console.log(data)
})
console.log('-----------------------------')

const p1 = new MyPromise((resolve, reject) => {
  resolve('ok')
})
const p2 = MyPromise.resolve('oh yeah')
const p3 = MyPromise.reject('error')
const p4 = MyPromise.resolve('oh yeah yeah')

const result1 = MyPromise.all([p1, p2, p3])
console.log('all_rejected\n', result1)
console.log('-----------------------------')
const result2 = MyPromise.all([p1, p2, p4])
console.log('all_fulfilled\n',result2)
const result3 = MyPromise.race([p1, p2, p3])
console.log('-----------------------------')
console.log('race\n',result3)

四、测试结果

在这里插入图片描述

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

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

相关文章

2024接口自动化测试入门基础知识【建议收藏】

接口自动化测试是指通过编写测试脚本和使用相关工具&#xff0c;对软件系统的接口进行自动化测试的过程。 今天本文从4个方面来介绍接口自动化测试入门基础知识 一、接口自动化测试是什么&#xff1f; 二、接口自动化测试流程&#xff1f; 三、接口自动化测试核心知识点有那些…

开始Java之旅

1.Java语言 java是一门优秀的程序设计语言&#xff0c;并且是一种半编译型&#xff0c;半解释型语言。 Java 语言源于 1991 年 4 月&#xff0c;Sun 公司 James Gosling博士 领导的绿色计划(Green Project) 开始启动&#xff0c;此计划最初的目标是开发一种能够在各种消费性电…

Threejs绘制传送带

接下来会做一个MES场景下的数字孪生&#xff0c;所以开始做车间相关的模型&#xff0c;不过还是尽量少用建模&#xff0c;纯代码实现&#xff0c;因为一方面可以动态使用&#xff0c;可以调节长度和宽度等&#xff0c; 下面这节就做一个简单的传送带&#xff0c;这是所有车间都…

学之思考试系统环境启动QA

学之思考试系统环境启动Q&A 目录 学之思考试系统环境启动Q&A后台代码启动失败:前台代码启动失败常见解决方式参考资料后台代码启动失败: 后端代码启动不成功,不能够自动导入maven,配置依赖; 使用idea打开到:\xzs-master\xzs-mysql-master\source\xzs这个路径下;…

函数的创建和调用及删除

Oracle从入门到总裁:​​​​​​https://blog.csdn.net/weixin_67859959/article/details/135209645 函数和存储过程非常类似&#xff0c;也是可以存储在 Oracle 数据库中的 PL/SQL代码块&#xff0c;但是有返回值。 可以把经常使用的功能定义为一个函数&#xff0c;就像系统…

使用Flask部署ppocr模型_3

PaddleOCR环境搭建、模型训练、推理、部署全流程&#xff08;Ubuntu系统&#xff09;_1_paddle 多进程推理-CSDN博客 PP-Structure 文档分析-CSDN博客 Pycharm的Terminal进入创建好的虚拟环境 有时候Pycharm的terminal中显示的是硬盘中的项目路径&#xff0c;但没有进入创建好…

Python 开发实现登陆和注册模块

Python 开发实现登陆和注册模块 一、案例介绍 本例设计一个用户登录和注册模块&#xff0c;使用Tkinter框架构建界面&#xff0c;主要用到画布、文本框、按钮等组件。涉及知识点&#xff1a;Python Tkinter界面编程、pickle数据存储。本例实现了基本的用户登录和注册互动界面…

ic基础|时序篇:握手协议valid和ready的时序优化

大家好&#xff0c;我是数字小熊饼干&#xff0c;一个练习时长两年半的ic打工人。我在两年前通过自学跨行社招加入了IC行业。现在我打算将这两年的工作经验和当初面试时最常问的一些问题进行总结&#xff0c;并通过汇总成文章的形式进行输出&#xff0c;相信无论你是在职的还是…

网络安全的守护者:防火墙的五个主要功能解析

防火墙是一种网络安全设备&#xff0c;用于保护计算机网络免受未经授权的访问、攻击和恶意软件的侵害。它通过监控、过滤和控制网络流量&#xff0c;实施安全策略&#xff0c;防止不安全的数据包进入或离开受保护的网络。 防火墙的五个主要功能&#xff1a; 1. 访问控制&#…

Web入门-Tomecat

黑马程序员JavaWeb开发教程 文章目录 一、简介1、Web服务器2、Tomcat 二、基本使用三、入门程序解析 一、简介 1、Web服务器 对HTTP协议操作进行封装&#xff0c;简化web程序开发部署Web项目&#xff0c;对外提供网上信息浏览服务 2、Tomcat 概念&#xff1a;Tomcat是Apach…

(回溯)记忆化搜索和dp

动态规划的核心就是 状态的定义和状态的转移 灵神 的 回溯改递归思路 首先很多动态规划问题都可以采用 回溯 的思想 回溯主要思想就是把 一个大问题分解成小问题 比如 采用子集类回溯问题中的核心思想-> 选或不选 或者 选哪个 记忆化搜索之后 我们可以发现 每个新节点依…

深度图转点云

一、理论分析 二、其他分析 1、相机内参 相机内参主要是四个参数fx,fy,u0,v0。要明白相机内参就是相机内部参数&#xff0c;是参考像素坐标系而言&#xff0c;有了这个前提&#xff0c;这四个参数也就很好理解了。 &#xff08;1&#xff09;首先&#xff0c;。其中F是相机的…

sora related

官方https://openai.com/research/video-generation-models-as-world-simulators 概述&#xff1a; sora可以生成变长的、不同分辨率的最长可到1分钟的视频&#xff1b;整体流程是 v i d e o c o m p r e s s i o n n e r w o r k ( v i d e o → l a t e n t ) p a t c h i…

HarmonyOS ArkUI实战开发-NAPI数据类型

在前两篇文章里笔者简单介绍了 NAPI 工程结构以及生成的 cpp 源码部分&#xff0c;其中 JS 应用层传递过来的数据被封装在了 napi_value 中&#xff0c;使用前先要转换成对应的 C/C 数据类型&#xff0c;C/C 端的数据也要转换成 napi_value 数据类型传递给 JS 应用层&#xff0…

大模型改变了NLP的游戏规则了吗

NLP已经死了吗&#xff1f; 自从 ChatGPT 横空出世以来&#xff0c;自然语言处理&#xff08;Natural Language Processing&#xff0c;NLP&#xff09; 研究领域就出现了一种消极的声音&#xff0c;认为大模型技术导致 NLP “死了”。在某乎上就有一条热门问答&#xff0c;大…

mac上VMware fusion net模式无法正常使用的问题

更新时间&#xff1a;2024年04月22日21:39:04 1. 问题 环境&#xff1a; intel芯片的macbook pro VMware fusion 13.5.1 无法将“Ethernet0”连接到虚拟网络“/dev/vmnet8”。在这里显示这个之后&#xff0c;应该是vmnet8的网段发生了冲突&#xff0c;所以导致无法正常使用…

一篇文章带您了解操作系统的体系结构

操作系统的体系结构有哪些&#xff1f; 我们可以利用时钟中断实现计时功能。 原语是一种特殊的程序&#xff0c;具有原子性。也就是说&#xff0c;这段程序的运行必须一气呵成&#xff0c;不能中断。 内核是操作系统最基本&#xff0c;最核心的部分。 实现操作系统内核功能的…

Opencv Python图像处理笔记一:图像、窗口基本操作

文章目录 前言一、输入输出1.1 图片读取显示保存1.2 视频读取保存1.3 文件读取保存 二、GUI2.1 窗口2.2 轨迹条2.3 画图2.4 鼠标回调 三、图像入门操作3.1 颜色空间转化3.2 通道分离合并3.3 添加边框3.4 算数操作 四、二值化4.1 普通4.2 自适应4.3 Otsu 参考 前言 随着人工智能…

PS入门|蒙版到底是个什么样的功能?看完就明白了

前言 前段时间一直说蒙版蒙版什么的&#xff0c;很多小伙伴估计都听得一头雾水。 抠个图要加蒙版&#xff0c;调个色要加蒙版。 小白感觉这个蒙版就像调味剂一样&#xff0c;啥都需要加一个蒙版。 动不动就加个蒙版&#xff0c;究竟是干啥用的&#xff1f; 今天咱们就深入来…

【深度学习-第5篇】使用Python快速实现CNN分类(模式识别)任务,含一维、二维、三维数据演示案例(使用pytorch框架)

在之前的文章中介绍了CNN的图解入门&#xff0c;CNN的MATLAB分类实现&#xff0c;CNN的MATLAB回归实现。 卷积神经网络(Convolutional Neural Networ&#xff0c;简称CNN)是一种广泛应用于图像识别领域的深度学习算法。它通过模拟人类视觉系统的层次结构&#xff0c;可以自动提…