Promise实现

Promise实现

const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'class MPromise {FULFILLED_CALLBACK_LIST = []REJECTED_CALLBACK_LIST = []_status = PENDINGconstructor(fn) {// 初始状态为pendingthis.status = PENDINGthis.value = nullthis.reason = nulltry {fn(this.resolve.bind(this), this.reject.bind(this))} catch (e) {this.reject(e)}}get status() {return this._status}set status(newStatus) {this._status = newStatusswitch (newStatus) {case FULFILLED: {this.FULFILLED_CALLBACK_LIST.forEach((callback) => {callback(this.value)})break}case REJECTED: {this.REJECTED_CALLBACK_LIST.forEach((callback) => {callback(this.reason)})break}}}resolve(value) {if (this.status === PENDING) {this.value = valuethis.status = FULFILLED}}reject(reason) {if (this.status === PENDING) {this.reason = reasonthis.status = REJECTED}}then(onFulfilled, onRejected) {const realOnFulfilled = this.isFunction(onFulfilled)? onFulfilled: (value) => {return value}const realOnRejected = this.isFunction(onRejected)? onRejected: (reason) => {throw reason}const promise2 = new MPromise((resolve, reject) => {const fulfilledMicrotask = () => {queueMicrotask(() => {try {const x = realOnFulfilled(this.value)this.resolvePromise(promise2, x, resolve, reject)} catch (e) {reject(e)}})}const rejectedMicrotask = () => {queueMicrotask(() => {try {const x = realOnRejected(this.reason)this.resolvePromise(promise2, x, resolve, reject)} catch (e) {reject(e)}})}switch (this.status) {case FULFILLED: {fulfilledMicrotask()break}case REJECTED: {rejectedMicrotask()break}case PENDING: {this.FULFILLED_CALLBACK_LIST.push(fulfilledMicrotask)this.REJECTED_CALLBACK_LIST.push(rejectedMicrotask)}}})return promise2}catch(onRejected) {return this.then(null, onRejected)}isFunction(param) {return typeof param === 'function'}resolvePromise(promise2, x, resolve, reject) {// 如果 newPromise 和 x 指向同一对象,以 TypeError 为据因拒绝执行 newPromise// 这是为了防止死循环if (promise2 === x) {return reject(new TypeError('The promise and the return value are the same'))}if (x instanceof MPromise) {// 如果 x 为 Promise ,则使 newPromise 接受 x 的状态// 也就是继续执行x,如果执行的时候拿到一个y,还要继续解析yqueueMicrotask(() => {x.then((y) => {this.resolvePromise(promise2, y, resolve, reject)}, reject)})} else if (typeof x === 'object' || this.isFunction(x)) {// 如果 x 为对象或者函数if (x === null) {// null也会被判断为对象return resolve(x)}let then = nulltry {// 把 x.then 赋值给 thenthen = x.then} catch (error) {// 如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promisereturn reject(error)}// 如果 then 是函数if (this.isFunction(then)) {let called = false// 将 x 作为函数的作用域 this 调用// 传递两个回调函数作为参数,第一个参数叫做 resolvePromise ,第二个参数叫做 rejectPromisetry {then.call(x,// 如果 resolvePromise 以值 y 为参数被调用,则运行 resolvePromise(y) => {// 需要有一个变量called来保证只调用一次.if (called) returncalled = truethis.resolvePromise(promise2, y, resolve, reject)},// 如果 rejectPromise 以据因 r 为参数被调用,则以据因 r 拒绝 promise(r) => {if (called) returncalled = truereject(r)})} catch (error) {// 如果调用 then 方法抛出了异常 e:if (called) return// 否则以 e 为据因拒绝 promisereject(error)}} else {// 如果 then 不是函数,以 x 为参数执行 promiseresolve(x)}} else {// 如果 x 不为对象或者函数,以 x 为参数执行 promiseresolve(x)}}static resolve(value) {if (value instanceof MPromise) {return value}return new MPromise((resolve) => {resolve(value)})}static reject(reason) {return new MPromise((resolve, reject) => {reject(reason)})}static race(promiseList) {return new MPromise((resolve, reject) => {const length = promiseList.lengthif (length === 0) {return resolve()} else {for (let i = 0; i < length; i++) {MPromise.resolve(promiseList[i]).then((value) => {return resolve(value)},(reason) => {return reject(reason)})}}})}
}
const test = new MPromise((resolve, reject) => {setTimeout(() => {reject(111)}, 1000)
}).then((value) => {console.log('then')}).catch((reason) => {console.log('catch')})MPromise.resolve(1).then((res) => {console.log(res, 'res')return 2}).then((res2) => {console.log(res2, 'res2')})
1 res
2 res2
catch

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

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

相关文章

分享一个 git stash 的实际使用场景。

当我将新的变更记录提交为 git commit --amend 后&#xff0c;发现这需要修改云端上的提交记录&#xff0c;也就是 vscode 中会出现这张图 于是&#xff0c;我通过 git reset head^ 撤销掉刚刚的提交。 reset 前&#xff1a; reset 后&#xff1a; 但在撤销的同时&#xf…

深入理解计算机网络分层结构

一、 为什么要分层&#xff1f; 计算机网络分层的主要目的是将复杂的网络通信过程分解为多个相互独立的层次&#xff0c;每个层次负责特定的功能。这样做有以下几个好处&#xff1a; 模块化设计&#xff1a;每个层次都有清晰定义的功能和接口&#xff0c;使得网络系统更易于设…

解决Xshell登录云服务器的免密码和云服务器生成子用户问题

Xshell登录云服务器的免密码问题 前言一、Xshell登录云服务器的免密码操作实践 二、centos创建用户创建用户实操删除用户更改用户密码直接删除子用户 前言 Xshell登录云服务器免密码问题的解决方案通常涉及使用SSH密钥对。用户生成一对密钥&#xff08;公钥和私钥&#xff09;…

Spring源码刨析之配置文件的解析和bean的创建以及生命周期

public void test1(){XmlBeanFactory xmlBeanFactory new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));user u xmlBeanFactory.getBean("user",org.xhpcd.user.class);// System.out.println(u.getStu());}先介绍一个类XmlBeanFac…

Linux —— FTP服务【从0-1】

目录 一、介绍 1.概述 2.FTP的传输模式 PORT 主动模式 PASV 被动模式 3.FTP服务的作用 二、搭建FTP服务器 FTP服务端配置 1.安装vsftpd文件服务 2.启动服务 3.防火墙配置 4.FTP服务相关文件说明 FTP客户端配置 1.安装FTP客户端工具 lftp 2.访问FTP服务器 Linux系…

探索量子计算:打开未来技术的大门

在科技领域&#xff0c;每一次技术革命都能开启新的可能性&#xff0c;推动人类社会进入一个新的时代。当前&#xff0c;量子计算作为一种前沿技术&#xff0c;正引领着下一轮科技革命的浪潮。本文将深入探索量子计算的奥秘&#xff0c;解析其工作原理&#xff0c;并通过一个简…

Windows10/11 重装之后,刷新原来的文件夹里的用户权限

将 d:\* 下所有文件的所有者&#xff0c;更改为Administrator takeown /F d:\WorkSpaces\* /R /A 赋予system、Administrator、Authenticated Users所有控制访问权限。可以自己改用户&#xff0c;删掉对应的即可 icacls d:\* /grant System:(F) /grant Administrator:(F) …

子集和问题(c++题解)

题目描述 子集和问题的一个实例为〈S,t〉。其中&#xff0c;S{ x1&#xff0c; x2&#xff0c;…&#xff0c; xn}是一个正整数的集合&#xff0c;c是一个正整 数。子集和问题判定是否存在S的一个子集S1&#xff0c;使得子集S1和等于c。 对于给定的正整数的集合S{ x1&#xf…

深度学习图像处理基础工具——opencv 实战2 文档扫描OCR

输入一个文档&#xff0c;怎么进行文档扫描&#xff0c;输出扫描后的图片呢&#xff1f; 今天学习了 opencv实战项目 文档扫描OCR 问题重构&#xff1a;输入图像 是一个含有文档的图像——> 目标是将其转化为 规则的扫描图片 那么怎么实现呢&#xff1f; 问题分解&#…

ELFK日志分析系统

目录 1. Elasticsearch 特点和功能&#xff1a; 使用场景&#xff1a; Elasticsearch 结构和术语&#xff1a; 2. Logstash Logstash 的特点和功能&#xff1a; Logstash 工作流程&#xff1a; Logstash 的插件&#xff08;Plugin&#xff09;&#xff1a; 3. Kibana …

Go 之常见的几种设计模式

学一学Go中常见的几种设计模式和对应的示例 单例模式 确保一个类型只有一个实例&#xff0c;同时提供一个全局访问点。 package mainimport "fmt"type Singleton struct {data string }var instance *Singletonfunc GetInstance() *Singleton {if instance nil {…

Python 复杂密码图形化生成工具,支持选择生成10位和12位复杂密码(初版)

代码 #!/usr/bin/env python # -*- coding: utf-8 -*- # Time : 2024/3/26 15:22 # Author : wyq # File : 部署测试.py import random import string from tkinter import *def generate_password(length):characters string.ascii_letters string.digits string.p…

HTML:链接

目录 一、超链接 二、 外联元素 一、<a>超链接 <a> 标签用于定义超链接&#xff0c;超链接可以让用户从一个网页跳转到另一个网页。 常用属性&#xff1a; href指定链接的目标地址。download表示链接是一个下载链接&#xff0c;指定下载的文件名。target 指定在…

JavaScript扩展运算符...的实现原理

… 作用 扩展运算符&#xff08;spread&#xff09;是三个点&#xff08;…&#xff09;&#xff0c;用于取出参数对象中的所有可遍历属性&#xff0c;浅拷贝到当前对象之中。 常见用法 1.浅拷贝数组 const a1 [test1, test2]; const a2 [...a1];a2[0] test2; a2 // [te…

【vue】Vue3开发中常用的VSCode插件

Vue - Official&#xff1a;vue的语法特性&#xff0c;如代码高亮&#xff0c;自动补全等 Vue VSCode Snippets&#xff1a;自定义一些代码片段 v3单文件组件vdata数据vmethod方法 别名路径跳转 参考 https://www.bilibili.com/video/BV1nV411Q7RX

学校4-11天梯赛选拔赛

目录 L1-5 6翻了 题目 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; 思路 AC代码 L1-1 嫑废话上代码 题目 输入格式&#xff1a; 输出格式&#xff1a; 输入样例&#xff1a; 输出样例&#xff1a; AC代码 L1-8 刮刮彩…

HDFS、Hive、Redis、MySQL、HBase、Kafka、Flink等常用技术架构是什么?架构核心是什么?架构工作流是什么?

这些常用的技术架构在大数据和分布式系统领域发挥着重要作用&#xff0c;每个都有其特定的用途和核心组件。 HDFS (Hadoop Distributed File System)&#xff1a; 架构核心&#xff1a;HDFS是Hadoop生态系统的一部分&#xff0c;用于存储大规模数据集&#xff0c;并提供高吞吐量…

代码随想录-二叉树

************二叉树的前序遍历&#xff1a; . - 力扣&#xff08;LeetCode&#xff09; 递归 public class LeetCode144 {class TreeNode{int val;TreeNode left;TreeNode right;public TreeNode() {}public TreeNode(int val) {this.val val;}public TreeNode(int val, Tre…

初识责任链模式--一起学习吧之数据库

一、定义 责任链模式是一种对象行为型模式&#xff0c;用于处理请求发送者和多个请求处理者之间的耦合问题。在这种模式中&#xff0c;请求的处理者通过前一对象记住其下一个对象的引用而连成一条链。当有请求发生时&#xff0c;请求会沿着这条链传递&#xff0c;直到有对象处…

深入了解边缘AI的发展

人工智能先进功能的融合、物联网设备的广泛采用以及边缘计算的强大性能释放了边缘AI的潜力。这种变革性的协同作用涵盖了辅助医疗诊断、自动驾驶和仓库物流自动化等应用。 边缘计算起源于1990年代的内容分发网络&#xff0c;现在被广泛使用&#xff0c;尤其是在边缘AI领域。企…