当前位置: 首页 > news >正文

测试驱动来学习 Promise

基础功能

  • 测试案例:以同步的方式调用。
/*** v1: 基础功能*/
const p1 = new MyPromise((resolve, reject) => {resolve('success')reject('error')
})p1.then((value) => {console.log('v1: ', value)
}) 
  • 实现功能:在 status 和 value 的位置暂存值,在 then 函数中取出。
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;constructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;}}then = (onFulfilled, onRejected) => {const callbackMap = {[FULFILLED]: onFulfilled,[REJECTED]: onRejected}callbackMap[this.status]?.(this.value)}
}

异步执行

  • 测试案例
/*** v2: 异步执行*/
const p2 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success') // 异步结束后调用}, 1000)
})p2.then((value) => {console.log('v2: ', value)
})
  • 实现功能
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;fulfilledCallback = null; // 暂存 rejectrejectedCallback = null; // 暂存 rejectconstructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;this.fulfilledCallback?.(value); // 异步结束后调用 resolve}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;this.rejectedCallback?.(value); // 异步结束后调用 reject}}then = (onFulfilled, onRejected) => {const callbackMap = {[FULFILLED]: onFulfilled,[REJECTED]: onRejected,[PENDING]: () => {this.fulfilledCallback = onFulfilled;this.rejectedCallback = onRejected;}}callbackMap[this.status]?.(this.value)}
}

异步时多个then

  • 测试案例
/*** v3: 异步时多个then*/
const p3 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success')}, 1000)
})p3.then((value) => {console.log('v3 - 1: ', value)
})
p3.then((value) => {console.log('v3 - 2: ', value)
})
// v3 - 1:  success
// v3 - 2:  success
  • 实现功能
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;fulfilledCallbacks = []; // 暂存 resolverejectedCallbacks = []; //  暂存 rejectconstructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;while (this.fulfilledCallbacks.length) { // 遍历执行所有的 resolvethis.fulfilledCallbacks.shift()?.(value);}}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;while (this.rejectedCallbacks.length) { // 遍历执行所有的 rejectthis.rejectedCallbacks.shift()?.(value);}}}then = (onFulfilled, onRejected) => {const callbackMap = {[FULFILLED]: onFulfilled,[REJECTED]: onRejected,[PENDING]: () => {this.fulfilledCallbacks.push(onFulfilled);  // 异步时多个thenthis.rejectedCallbacks.push(onRejected);}}callbackMap[this.status]?.(this.value)}
}

链式调用

  • 测试案例
const p4 = new MyPromise((resolve, reject) => {setTimeout(() => {resolve('success')}, 1000)
})p4.then((value) => {console.log('v4 - 1: ', value)return 1;
}).then((value) => {console.log('v4 - 2: ', value)return 2;
})
// v4 - 1:  success
// v4 - 2:  1
  • 实现功能
const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MyPromise {status = PENDING;value = null;fulfilledCallbacks = [];rejectedCallbacks = [];constructor(executor) {executor(this.resolve, this.reject);}resolve = (value) => {if (this.status === PENDING) {this.status = FULFILLED;this.value = value;while (this.fulfilledCallbacks.length) {this.fulfilledCallbacks.shift()?.(value);}}}reject = (value) => {if (this.status === PENDING) {this.status = REJECTED;this.value = value;while (this.rejectedCallbacks.length) {this.rejectedCallbacks.shift()?.(value);}}}then = (onFulfilled, onRejected) => {return new MyPromise((resolve, reject) => {const fulfilledTask = (value) => {const res = onFulfilled(value); // 将上一个 Promise 的 resolve 结果传入当前 Promiseresolve(res);   // 确保返回的 Promise 被执行}const rejectedTask = (value) => {const res = onRejected(value);reject(res);    // 确保返回的 Promise 被执行}const callbackMap = {[FULFILLED]: fulfilledTask,[REJECTED]: rejectedTask,[PENDING]: () => {this.fulfilledCallbacks.push(fulfilledTask);  // 异步时多个thenthis.rejectedCallbacks.push(rejectedTask);    // 异步时多个then}}callbackMap[this.status]?.(this.value)})}
}

返回自身

  • 测试案例
/*
* v6: 返回自身
*/
const p6 = new MyPromise((resolve, reject) => {resolve(1);
});const p62 = p6.then((res) => {console.log(res);return p62;
});
p62.then(() => { },(err) => console.log(err)
);

相关文章:

测试驱动来学习 Promise

基础功能 测试案例:以同步的方式调用。 /*** v1: 基础功能*/ const p1 new MyPromise((resolve, reject) > {resolve(success)reject(error) })p1.then((value) > {console.log(v1: , value) }) 实现功能:在 status 和 value 的位置暂存值&…...

Vue3实战笔记(20)—封装头部导航组件

文章目录 前言一、封装头部导航栏二、使用步骤总结 前言 Vue 3 封装头部导航栏有助于提高代码复用性、统一风格、降低维护成本、提高可配置性和模块化程度,同时还可以实现动态渲染等功能,有利于项目开发和维护。 一、封装头部导航栏 封装头部导航栏&am…...

Yolov8目标检测——在Android上部署Yolov8 tflite模型

1. 简介 YOLOv8 是一种用于目标检测的深度学习模型,它是 YOLO(You Only Look Once)系列的最新版本之一。YOLO 系列因其高效和准确性而在计算机视觉领域非常受欢迎,特别是在需要实时目标检测的应用中,如视频监控、自动…...

(delphi11最新学习资料) Object Pascal 学习笔记---第12章操作类(类方法和类数据)

第12章 操作类 ​ 在过去的几章中,你已经了解了 Object Pascal 语言面向对象的基础:类、对象、方法、构造函数、继承、后期绑定、接口等等。现在,我们需要进一步了解与类管理相关的一些更高级、更具体的语言特性。从类引用到类助手(class he…...

面向 C# 开发人员的电子邮件转换控件 - EML 到 PNG

本文将使 C# 开发人员能够以编程方式将EML或MSG转换为其他流行的文件格式。Aspose.Email 提供了类和方法以及在线 电子邮件转换器工具,可将 EML无缝转换为PNG 。如果不安装第三方软件,则无法打开 EML/MSG 文件。因此,将 EML/MSG 转换为 PNG 和…...

Vue3:数据交互axios

回调函数 > 回调函数: 一些特殊的函数,表示未来才会执行的一些功能,后续代码不会等待该函数执行完毕就开始执行了 1. Promise 1.1 简介 > 前端中的异步编程技术,类似Java中的多线程线程结果回调! * Promise 是异步编程的一种解决方案&#xff0c…...

芯片的性能指什么

【省带宽、压成本专题】降低30%视频码率,深挖“窄带高清”的实现原理 - 知乎 芯片(或微处理器、集成电路)的性能主要指其完成特定任务的能力和效率。性能可以通过多种参数来衡量,这些参数反映了芯片设计的不同方面,包…...

Java通过百度地图API获取定位-普通IP定位

项目中有一个登录邮箱提醒的功能,需要根据IP地址获取定位信息,从而更好地提示用户账号登录的所在地。为此,花费了一些时间来实现这个功能。 在CSDN搜索了一下,发现关于获取定位的文章说明都不够详细,于是决定自己创作一…...

5月13号作业

使用消息队列实现的2个终端之间的互相聊天 并使用信号控制消息队列的读取方式: 当键盘按ctrlc的时候,切换消息读取方式,一般情况为读取指定编号的消息,按ctrlc之后,指定的编号不读取,读取其他所有编号的消息…...

【计算机网络】Socket网络编程

💻文章目录 📄前言Socket编程基础概念工作原理 Socket API介绍socket函数绑定、监听函数accept、connect接受/发送函数 Socket API的应用Socket类与其派生类的设计服务器与客户端的设计使用 📓总结 📄前言 现今我们的日常生活当中…...

Ansible自动运维工具之playbook

目录 一.inventory主机清单 1.定义 2.变量 (1)主机变量 (2)组变量 (3)组嵌套 二.playbook基本内容 1.组成 (1)Tasks: 任务,即调用模块完成的某操作 &#xff0…...

【启明智显技术分享】SSD201/SSD202D核心板UI界面开发全攻略:LVGL使用指南

提示:作为Espressif(乐鑫科技)大中华区合作伙伴及sigmastar(厦门星宸)VAD合作伙伴,我们不仅用心整理了你在开发过程中可能会遇到的问题以及快速上手的简明教程供开发小伙伴参考。同时也用心整理了乐鑫及星宸…...

数据可视化(九):Pandas北京租房数据分析——房源特征绘图、箱线图、动态可视化等高级操作

Tips:"分享是快乐的源泉💧,在我的博客里,不仅有知识的海洋🌊,还有满满的正能量加持💪,快来和我一起分享这份快乐吧😊! 喜欢我的博客的话,记得…...

ADOP带你了解:跳线与交叉电缆有何不同?

如果您想将设备连接到互联网,您可能想知道要使用的正确电缆。跳线和交叉电缆都是类型的以太网电缆,可帮助连接计算机、调制解调器、路由器和交换机等设备。那么,跳线和交叉电缆有什么区别呢?让我们讨论这两种类型的电缆&#xff0…...

Django 和 Spring Boot

标题 Django (Python)Django提供的组件Django 的处理逻辑 Spring Boot (Java)Spring Boot 的特点Spring Boot 的处理逻辑 MVC设计模式模型(Model)视图(View)控制器(Controller)逻辑处理过程 Django 和 Spri…...

上位机图像处理和嵌入式模块部署(树莓派4b的替代品)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 实话实说,树莓派4b的产品力还是比较优秀的,价格还算适中。但是和国产卡片电脑比起来,则逊色不少。功能差不多的…...

Springboot整合 Spring Cloud Gateway

1.Gateway介绍 1.是spring cloud官方推出的响应式的API网关框架,旨在为微服务架构提供一种简单有效的API路由的管理方式,并基于Filter的方式提供网关的基本功能,例如:安全认证,监控,限流等等。 2.功能特征…...

Rust开发工具有哪些?

目录 一、JetBrains公司的RustRover​编辑 二、微软公司的Visual Studio Code 三、Rust编译工具 一、JetBrains公司的RustRover RustRover是由JetBrains开发的一款专为Rust开发量身定制的新兴IDE,目前还处于早期访问阶段。它支持Rust、Cargo、TOML、Web和数据库等…...

20240514基于深度学习的弹性超材料色散关系预测与结构逆设计

论文:Dispersion relation prediction and structure inverse design of elastic metamaterials via deep learning DOI:https://doi.org/10.1016/j.mtphys.2022.100616 1、摘要 精心设计的超材料结构给予前所未有的性能,保证了各种各样的具…...

SAP:FI 财务凭证行项目文本前台修改

一、问题描述 财务凭证行项目文本点击修改,但是前台有的行可以修改,有的行是灰色的不能修改,如下图所示,这个文本信息有误,必须修改怎么办? 二、思路分析 有的行可以修改,有的行不能修改&#x…...

IDEA运行Tomcat出现乱码问题解决汇总

最近正值期末周,有很多同学在写期末Java web作业时,运行tomcat出现乱码问题,经过多次解决与研究,我做了如下整理: 原因: IDEA本身编码与tomcat的编码与Windows编码不同导致,Windows 系统控制台…...

19c补丁后oracle属主变化,导致不能识别磁盘组

补丁后服务器重启,数据库再次无法启动 ORA01017: invalid username/password; logon denied Oracle 19c 在打上 19.23 或以上补丁版本后,存在与用户组权限相关的问题。具体表现为,Oracle 实例的运行用户(oracle)和集…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad(Adaptive Gradient Algorithm)是一种自适应学习率的优化算法,由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率,适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂

蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...

前端导出带有合并单元格的列表

// 导出async function exportExcel(fileName "共识调整.xlsx") {// 所有数据const exportData await getAllMainData();// 表头内容let fitstTitleList [];const secondTitleList [];allColumns.value.forEach(column > {if (!column.children) {fitstTitleL…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

数据库分批入库

今天在工作中,遇到一个问题,就是分批查询的时候,由于批次过大导致出现了一些问题,一下是问题描述和解决方案: 示例: // 假设已有数据列表 dataList 和 PreparedStatement pstmt int batchSize 1000; // …...

多种风格导航菜单 HTML 实现(附源码)

下面我将为您展示 6 种不同风格的导航菜单实现&#xff0c;每种都包含完整 HTML、CSS 和 JavaScript 代码。 1. 简约水平导航栏 <!DOCTYPE html> <html lang"zh-CN"> <head><meta charset"UTF-8"><meta name"viewport&qu…...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

LLMs 系列实操科普(1)

写在前面&#xff1a; 本期内容我们继续 Andrej Karpathy 的《How I use LLMs》讲座内容&#xff0c;原视频时长 ~130 分钟&#xff0c;以实操演示主流的一些 LLMs 的使用&#xff0c;由于涉及到实操&#xff0c;实际上并不适合以文字整理&#xff0c;但还是决定尽量整理一份笔…...