【Promise】自定义promise
文章目录
- 1 定义整体结构
- 2 Promise 构造函数的实现
- 3 promise.then()与promise.catch()的实现
- 4 Promise.resolve()与Promise.reject()的实现
- 5 Promise.all与Promise.race()的实现
- 6 Promise.resolveDelay()与Promise.rejectDelay()的实现
1 定义整体结构
/*自定义 Promise
*/
(function (window) {
/*
Promise 构造函数
excutor: 内部同步执行的函数 (resolve, reject) => {}
*/
function Promise(excutor) {
}/*为 promise 指定成功/失败的回调函数
函数的返回值是一个新的 promise 对象
*/
Promise.prototype.then = function (onResolved, onRejected) {
}/*为 promise 指定失败的回调函数
是 then(null, onRejected)的语法糖
*/
Promise.prototype.catch = function (onRejected) {
}/*返回一个指定了成功 value 的 promise 对象
*/
Promise.resolve = function (value) {
}/*返回一个指定了失败 reason 的 promise 对象
*/
Promise.reject = function (reason) {
}/*返回一个 promise, 只有 promises 中所有 promise 都成功时, 才最终成功, 只要有一个失败就直接失败
*/
Promise.all = function (promises) {
}/*返回一个 promise, 一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝
*/
Promise.race = function (promises) {
}// 暴露构造函数
window.Promise = Promise
})(window)
2 Promise 构造函数的实现
/*
Promise 构造函数
excutor: 内部同步执行的函数 (resolve, reject) => {}
*/
function Promise(excutor) {const self = thisself.status = 'pending' // 状态值, 初始状态为 pending, 成功了变为resolved, 失败了变为 rejectedself.data = undefined // 用来保存成功 value 或失败 reason 的属性self.callbacks = [] // 用来保存所有待调用的包含 onResolved 和 onRejected 回调函数的对象的数组/*异步处理成功后应该调用的函数value: 将交给 onResolve()的成功数据*/function resolve(value) {if(self.status!=='pending') { // 如果当前不是 pending, 直接结束return}// 立即更新状态, 保存数据self.status = 'resolved'self.data = value// 异步调用所有待处理的 onResolved 成功回调函数if (self.callbacks.length>0) {setTimeout(() => {self.callbacks.forEach(obj => {obj.onResolved(value)})})}}/*异步处理失败后应该调用的函数reason: 将交给 onRejected()的失败数据*/function reject(reason) {if(self.status!=='pending') { // 如果当前不是 pending, 直接结束return}// 立即更新状态, 保存数据self.status = 'rejected'self.data = reason// 异步调用所有待处理的 onRejected 回调函数setTimeout(() => {self.callbacks.forEach(obj => {obj.onRejected(reason)})})}try {// 立即同步调用 excutor()处理excutor(resolve, reject)} catch (error) { // 如果出了异常, 直接失败reject(error)}
}
3 promise.then()与promise.catch()的实现
/*为 promise 指定成功/失败的回调函数
函数的返回值是一个新的 promise 对象
*/
Promise.prototype.then = function (onResolved, onRejected) {const self = this// 如果 onResolved/onRejected 不是函数, 可它指定一个默认的函数onResolved = typeof onResolved==='function' ? onResolved : value => value // 指定返回的 promise 为一个成功状态, 结果值为 valueonRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason} // 指定返回的 promise 为一个失败状态, 结果值为 reason// 返回一个新的 promise 对象return new Promise((resolve, reject) => {/*专门抽取的用来处理 promise 成功/失败结果的函数callback: 成功/失败的回调函数*/function handle(callback) {// 1. 抛出异常 ===> 返回的 promise 变为 rejectedtry {const x = callback(self.data)// 2. 返回一个新的 promise ===> 得到新的 promise 的结果值作为返回的promise 的结果值if (x instanceof Promise) {x.then(resolve, reject) // 一旦 x 成功了, resolve(value), 一旦 x失败了: reject(reason)} else {// 3. 返回一个一般值(undefined) ===> 将这个值作为返回的 promise 的成功值resolve(x)}} catch (error) {reject(error)}}if (self.status === 'resolved') { // 当前 promise 已经成功了setTimeout(() => {handle(onResolved)})} else if (self.status === 'rejected') { // 当前 promise 已经失败了setTimeout(() => {handle(onRejected)})} else { // 当前 promise 还未确定 pending// 将 onResolved 和 onRejected 保存起来self.callbacks.push({onResolved(value) {handle(onResolved)},onRejected(reason) {handle(onRejected)}})}})
}
4 Promise.resolve()与Promise.reject()的实现
/*返回一个指定了成功 value 的 promise 对象
value: 一般数据或 promise
*/
Promise.resolve = function (value) {return new Promise((resolve, reject) => {if (value instanceof Promise) {value.then(resolve, reject)} else {resolve(value)}})
}/*
返回一个指定了失败 reason 的 promise 对象
reason: 一般数据/error
*/
Promise.reject = function (reason) {return new Promise((resolve, reject) => {reject(reason)})
}
5 Promise.all与Promise.race()的实现
/*返回一个新的 promise 对象, 只有 promises 中所有 promise 都产生成功 value 时, 才最
终成功, 只要有一个失败就直接失败
*/
Promise.all = function (promises) {// 返回一个新的 promisereturn new Promise((resolve, reject) => {// 已成功的数量let resolvedCount = 0// 待处理的 promises 数组的长度const promisesLength = promises.length// 准备一个保存成功值的数组const values = new Array(promisesLength)// 遍历每个待处理的 promisefor (let i = 0; i < promisesLength; i++) {// promises 中元素可能不是一个数组, 需要用 resolve 包装一下Promise.resolve(promises[i]).then(value => {// 成功当前 promise 成功的值到对应的下标values[i] = value// 成功的数量加 1resolvedCount++// 一旦全部成功if(resolvedCount===promisesLength) {// 将所有成功值的数组作为返回 promise 对象的成功结果值resolve(values)}},reason => {// 一旦有一个promise产生了失败结果值, 将其作为返回promise对象的失败结果值reject(reason)})}})
}/*返回一个 promise,一旦某个 promise 解决或拒绝, 返回的 promise 就会解决或拒绝。
*/
Promise.race = function (promises) {// 返回新的 promise 对象return new Promise((resolve, reject) => {// 遍历所有 promisefor (var i = 0; i < promises.length; i++) {Promise.resolve(promises[i]).then((value) => { // 只要有一个成功了, 返回的 promise 就成功了resolve(value)},(reason) => { // 只要有一个失败了, 返回的结果就失败了reject(reason)})}})
}
6 Promise.resolveDelay()与Promise.rejectDelay()的实现
/*返回一个延迟指定时间才确定结果的 promise 对象
*/
Promise.resolveDelay = function (value, time) {return new Promise((resolve, reject) => {setTimeout(() => {if (value instanceof Promise) { // 如果 value 是一个 promise, 取这个promise 的结果值作为返回的 promise 的结果值value.then(resolve, reject) // 如果 value 成功, 调用resolve(val), 如果 value 失败了, 调用 reject(reason)} else {resolve(value)}}, time);})
}/*返回一个延迟指定时间才失败的 Promise 对象
*/
Promise.rejectDelay = function (reason, time) {return new Promise((resolve, reject) => {setTimeout(() => {reject(reason)}, time)})
}
相关文章:
【Promise】自定义promise
文章目录 1 定义整体结构2 Promise 构造函数的实现3 promise.then()与promise.catch()的实现4 Promise.resolve()与Promise.reject()的实现5 Promise.all与Promise.race()的实现6 Promise.resolveDelay()与Promise.rejectDelay()的实现 1 定义整体结构 /*自定义 Promise */ (f…...
Docker容器部署Windows系统教程
本章教程,使用Docker容器部署一个Windows操作系统容器。 一、拉取容器 dockurr/windows:latest二、运行容器 docker run -dit --name win11 -v $PWD:/share -v /opt/iso/win11.iso:/custom.iso -p 3389:3389 -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-tim…...
js id数组转字符串
在 JavaScript 中,将数组转换为字符串有几种常见的方法。每种方法都有其特定的用途和格式。以下是一些常用的方法: 1. Array.prototype.join(separator) join 方法将数组的所有元素连接成一个字符串,并使用指定的分隔符(默认为逗…...
如何在 Android 上增加 SELinux 权限
SELinux(Security-Enhanced Linux)是一种强制访问控制(MAC)机制,它为 Android 系统提供了额外的安全层。通过 SELinux,系统管理员可以定义细粒度的安全策略,限制进程对文件、网络和其他资源的访…...
MySQL:数据类型建表
问题:我想建一个名为create和database的库可以吗? 如果按照一般的类型来建带有关键字的库 就会出现报错 如果我们这样写的话:关键词 ,则会建库成功。 选择要进行操作的数据库 use数据库 判断选择的库是否成功 删除数据库 drop…...
Linux:版本控制器git的简单使用+gdb/cgdb调试器的使用
一,版本控制器git 1.1概念 为了能够更方便我们管理不同版本的文件,便有了版本控制器。所谓的版本控制器,就是能让你 了解到⼀个文件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录工程的每⼀次改动和版本迭代的⼀个…...
【React.js】AntDesignPro左侧菜单栏栏目名称不显示的解决方案
作者:CSDN-PleaSure乐事 欢迎大家阅读我的博客 希望大家喜欢 使用环境:WebStorm 目录 问题概述 原因 解决方案 解决方法 潜在问题修改 最终效果呈现 额外内容 管理员界面路由配置 WebStorm背景更换 法一: 法二: 问题概…...
力扣力扣力:91.解码方法
91. 解码方法 - 力扣(LeetCode) 在完成动态规划入门之后,我们先整一个中档题,也是前面简单题的变体。 分析思路: 在拿到最终结果之前,我们应该明确什么样的数字序列能够解码。 规则1:由于只有…...
一些面试题总结(二)
21、TCP的四次挥手? 在断开TCP连接时,需要通过四次挥手来断开,过程是: (1)客户端向服务端发送FIN1和序列号SEQx的数据包,用来关闭客户端到服务端的数据传送。然后客户端进入 FIN-WAIT-1 状态。 (2)服务端接收FIN后,…...
Hive-testbench套件使用文档
Hive-testbench套件使用文档 hive-testbench 是hortonworks的一个开源项目,用于测试和基准测试 Apache Hive 的工具集。它提供了一系列的测试数据集和查询样例,用于评估和比较 Hive 在不同配置和环境下的性能。hive-testbench 的主要目标是模拟真实的大规模数据集和复杂查询…...
大数据新视界 -- 大数据大厂之 Impala 性能优化:新技术融合的无限可能(下)(12/30)
💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…...
Python | Leetcode Python题解之第540题有序数组中的单一元素
题目: 题解: class Solution:def singleNonDuplicate(self, nums: List[int]) -> int:low, high 0, len(nums) - 1while low < high:mid (low high) // 2mid - mid & 1if nums[mid] nums[mid 1]:low mid 2else:high midreturn nums[l…...
AHB Matrix 四星级 验证笔记(2.4) Tt3.3AHB总线协议测试时的 并行数据
文章目录 前言一、代码二、错误1.地址范围2. 并行执行线程中变量覆盖的情况3.有关incr的beat 前言 来源路科验证本节搞定 T3.3 AHB总线协议的覆盖:AHB_PROTOCOL_COVER 即测试ahb slave接口和master接口支持(尽可能)全部的ahb协议传输场景&am…...
前端零基础学习Day-Eight
CSS字体和文本样式 CSS文字样式 字体:font-family 语法:font-family:[字体1][,字体2][,...] p{font-family:"微软雅黑","宋体","黑体";} 含空格字体名和中文,用英文引号括起 属性值:具体字体名&…...
贪心算法day3(最长递增序列问题)
目录 1.最长递增三元子序列 2.最长连续递增序列 1.最长递增三元子序列 题目链接:. - 力扣(LeetCode) 思路:我们只需要设置两个数进行比较就好。设a为nums[0],b 为一个无穷大的数,只要有比a小的数字就赋值…...
【论文复现】MSA+抑郁症模型总结(三)
📝个人主页🌹:Eternity._ 🌹🌹期待您的关注 🌹🌹 ❀MSA抑郁症模型 热门研究领域:情感计算的横向发展1. 概述2. 论文地址3. 研究背景4. 主要贡献5. 模型结构和代码6. 数据集介绍7. 性…...
【软件测试】敏捷模型(Scrum模型)和V模型、W模型
敏捷模型 前面的那些模型以前非常流行,但现在开发人员在使用的时候会遇到各种问题。主要困难包括在项目开发期间处理来自客户的变更请求,以及合并这些变更所需要的高成本和时间。 在实际工作中,一款产品的功能是不断在变化的 所以为了克服这…...
【go从零单排】接口(interface)和多态(Polymorphism)
🌈Don’t worry , just coding! 内耗与overthinking只会削弱你的精力,虚度你的光阴,每天迈出一小步,回头时发现已经走了很远。 📗概念 在Go语言中,interface 是一种重要的类型,用于定义一组方法…...
SI5319C-C-GM,SiliconLabs芯科 SI5319C-C-GMR,时钟合成器/抖动清除器 封装 QFN-36 在售 20000PCS 23+
SI5319C-C-GM是SiliconLabs公司生产的时钟合成器和抖动清除器。它是一款高性能的时钟解决方案,可用于各种应用领域,包括通信、数据中心、消费电子等。 该器件采用了SiliconLabs独有的DSPLL技术,能够提供低抖动和高精度的时钟信号。它具有多个…...
使用批处理脚本批量删除Maven无效依赖
背景 在开发过程中,我们经常会遇到以下情况: 在pom.xml文件中错误地指定了依赖的名称。因为网络问题,某些依赖下载不完全。依赖版本号错误,导致下载的文件无法使用。 这些情况会导致Maven在本地仓库中留下一些无效的文件&#…...
3D打印技术如何重塑消费电子供应链:从原型验证到小批量生产
1. 项目概述:当3D打印遇上消费电子最近几年,我身边不少做产品设计、硬件开发的朋友,聊天时总会不约而同地提到一个词:3D打印。以前大家觉得这玩意儿就是个做手办、打样机的“玩具”,但现在风向明显变了。尤其是在消费电…...
IoTDB与TimechoDB深度解析
全球物联网设备将在2025年突破416亿台,每天产生79.4ZB的数据,相当于8000多万个1TB硬盘才能装下。面对这场数据海啸,传统数据库纷纷“侧漏”,时序数据库成为企业数字化升级的“救生艇”。 本文将从五大核心维度,系统剖…...
英伟达收购SwiftStack:AI时代从算力到数据管道的战略布局
1. 项目概述:一次战略收购的深度拆解最近在梳理科技巨头的战略动向时,一个几年前的老新闻——“英伟达收购SwiftStack”——重新进入了我的视野。乍一看,这似乎只是一次普通的商业并购,一个做GPU的巨头买下了一家名不见经传的软件…...
抠图怎么制作?2026年最全工具对比指南,一键搞定透明背景
五一假期,我被朋友们的"抠图需求"整崩溃了。换证件照底色、制作商品图、去掉背景重新合成……各种场景都来了一遍。索性我决定把这几年用过的抠图工具都总结一下,给大家写篇真实体验文章。说实话,抠图这件事看似简单,但…...
2026厦门国际智能交通运输产业博览会开幕:海外需求与国内先进技术的双向奔赴
2026年5月13日,为期三天的2026厦门国际智能交通运输产业博览会(CITSE 2026,以下简称“智交会”)隆重开幕。本届智交会由中国智能交通协会联合厦门会展集团股份有限公司共同举办,以“聚焦产业创新变革,赋能出…...
从C代码到汇编:图解函数调用栈中rsp和rbp的“职责分工”
从C代码到汇编:图解函数调用栈中rsp和rbp的"职责分工" 在计算机程序的执行过程中,函数调用是最基础也最核心的概念之一。当我们从高级语言如C/C深入到汇编层面时,会发现函数调用的背后隐藏着一套精密的栈帧管理机制。本文将带您走进…...
ubuntu linux虚拟机安装部署hermes详细教程(安装、问题处理)
文章目录 前言 一、Hermes 介绍 1. 什么是 Hermes Agent? 2. 核心特性 3. 为什么选择 Hermes Agent? 4. 适用场景 二、安装Hermes 1.安装 2.配置 3.开始对话 4.接入多平台(可选) 5.保持更新 三、Hermes接入微信 四、常见错误解决 1.Failed to connect to github.com port 4…...
2026年南京本地实测整理,值得入手的高性价比全屋定制品牌推荐
讲真,南京准备装房子、换柜子的姊妹们、老少爷们,谁没为全屋定制头大过?刚收了江北核心区的新房,还是鼓楼老破小准备翻新,跑了三五家门店就会发现:水太深了!低价套餐勾你进去,签约后…...
react native expo打包
打包原文 核心主题 使用 Expo EAS(Expo Application Services)官方云打包服务,无需本地安装 Android Studio 或配置 Android SDK,直接在云端生成 .apk 文件。 详细步骤 1. 全局安装 EAS CLI(只需一次) n…...
从DC到DCG:手把手教你搭建物理感知综合流程(含DEF文件处理避坑指南)
从DC到DCG:物理感知综合全流程实战指南 在28nm以下工艺节点,传统逻辑综合工具已难以应对复杂的物理效应。我们团队在最近一次5nm芯片项目中,由于初期忽视物理感知综合的约束设置,导致时序收敛多耗费三周时间。本文将分享从Design …...
