手写一个Promise,实现基本的链式调用

JavaScript 中的 Promise 进阶:手写实现与原理分析 本文旨在帮助读者深入理解 JavaScript Promise 的内部实现原理,通过手写一个简化版 Promise 来掌握其核心机制。内容涵盖 Promise 的基本概念、状态管理、then 方法实现、链式调用、错误处理等核心特性。从生活实例引入 Promise 概念解释 Promise 核心原理和状态机制分步骤手写实现 Promise分析 Promise 与事件循环的关系实际应用场景和常见问题解答Promise:表示一个异步操作的最终完成(或失败)及其结果值的对象。 阅读详情

手写 Promise 不废话上代码

	// 基础框架
	function myPromise(promiseCallback) {
		let self = this;
		self.status = "pending"; 				// 状态
		self.value = null; 						// 成功结果
		self.error = null; 						// 失败原因
		self.onResolvedCallbacks = [];
		self.onRejectedCallbacks = [];

		// 成功的回调
		function resolve(value) {
			if (self.status === 'pending') {	// 状态处理
				self.status = 'fulfilled'; 		// 保存成功的状态
				self.value = value; 			// 保存成功的结果
				self.onResolvedCallbacks.forEach(item => item(value)); // 方法依次取出
			}
		}
		// 失败的回调
		function reject(error) {
			if (self.status === 'pending') {
				self.status = 'rejected'; 		// 保存错误的状态
				self.error = error; 			// 保存错误的结果
				self.onRejectedCallbacks.forEach(item => item(error));
			}
		}
		// 立即执行promise参数的回调
		try {
			promiseCallback(resolve, reject);
		} catch (e) {
			reject(e);
		}
	}
	// 原型上注入then方法
	myPromise.prototype.then = function(onFulfilled, onRejected) {
		onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value;
		onRejected = typeof onRejected === "function" ? onRejected : (reason) => { throw reason };
		/*** 发布订阅模式 ***/
		if (this.status === "pending") {
			return new myPromise((resolve, reject) => {
				this.onResolvedCallbacks.push(() => {
					const fn = onFulfilled(this.value);
					fn instanceof myPromise ? fn.then(resolve, reject) : resolve(fn);
				});
				this.onRejectedCallbacks.push(() => {
					const fn = onRejected(this.error);
					fn instanceof myPromise ? fn.then(resolve, reject) : resolve(fn);
				});
			});
		}
		if (this.status === "fulfilled") {
			return new myPromise((resolve, reject) => {
				try {
					const fn = onFulfilled(this.value);
					fn instanceof myPromise ? fn.then(resolve, reject) : resolve(fn);
				} catch (err) { reject(err); }
			});
		}
		if (this.status === "rejected") {
			return new myPromise((resolve, reject) => {
				try {
					const fn = onRejected(this.error);
					fn instanceof myPromise ? fn.then(resolve, reject) : resolve(fn);
				} catch (error) { reject(error); }
			});	
		}
	}
	// 原型上注入catch方法
	myPromise.prototype.catch = function(onRejected) {
		return this.then(null, onRejected);
	}

	// 创建myPromise实例化对象
	let promiseTest = new myPromise((resolve, reject) => {
		console.log("myPromise1");
		setTimeout(e => resolve("myPromise1"), 300);
	});

	// 链式调用示例
	promiseTest
	.then(data => {
		console.log("then1:",data);
		return new myPromise((resolve, reject) => {
			console.log("myPromise2");
			setTimeout(e => resolve("promise2"), 300);
		});
	})
	.then(data => {
		console.log("then2:",data);
		return new myPromise((resolve, reject) => {
			console.log("myPromise3");
			setTimeout(e => resolve("promise3"), 300);
		});
	})
	.then(data => {
		console.log("then3:",data);
	})
	.catch(e => console.log(e))

在这里插入图片描述


手写 Promise 简要思路:

  1. 建立基本框架,即构建myPromise的构造函数,内部定义基本的属性,如状态、成功结果、失败原因,成功毁掉、失败回调等
  2. myPromise构造函数原型上增加then、catch等方法
  3. myPromise构造函数内执行其参数回调函数
  4. 进入成功或失败的回调函数中,修改状态
  5. then中执行发布订阅模式,then参数的回调方法进行存储

附:Promise 运行机制简述

在 JavaScript 中,Promise 是一种用于处理异步操作的对象。Promise 有三种状态:待定(pending)、已完成(fulfilled)和已拒绝(rejected)。一个 Promise 对象在创建后会一直处于待定状态,直到它被解决为止。

Promise 对象的运行机制如下:

  1. 创建 Promise 对象:通过调用 Promise 构造函数创建一个 Promise 对象,这个构造函数需要传入一个回调函数作为参数。这个回调函数包含两个参数:resolve 和 reject。
  2. 处理异步操作:在 Promise 对象中,异步操作是通过回调函数来实现的。当异步操作完成后,调用 resolve 方法将 Promise 对象的状态设置为已完成,或者调用 reject 方法将 Promise 对象的状态设置为已拒绝。
  3. 处理 Promise 对象的状态:当 Promise 对象的状态改变时,会触发 Promise 对象的 then 或 catch 方法。如果 Promise 对象的状态是已完成,then 方法会接收一个回调函数作为参数,这个回调函数会被调用,并且传入异步操作的结果作为参数。如果 Promise 对象的状态是已拒绝,catch 方法会接收一个回调函数作为参数,这个回调函数会被调用,并且传入错误信息作为参数。
  4. 链式调用:由于 Promise 对象的 then 和 catch 方法都会返回一个新的 Promise 对象,因此可以链式调用这些方法,处理异步操作的结果。

总的来说,Promise 对象的运行机制是通过创建 Promise 对象,处理异步操作,处理 Promise 对象的状态,以及链式调用 Promise 对象的 then 和 catch 方法来实现的。


前端面试必看之手写promise实现方法 通过实现一个简化版的Promise状态管理的重要性以及如何设计不可逆状态。使用回调队列处理异步任务。then和catch的核心逻辑以及链式调用的实现。手写Promise是学习异步编程的好方法,也为日常开发中更深入地理解Promise提供了帮助。 阅读详情

相关推荐

《数据分析岗笔试高频题:字节常用的SQL与AB测试考题解析》

• 核心考点:用RANK()/DENSE_RANK()/ROW_NUMBER()排序,SUM() OVER()计算累积值。◦ 用公式n=2*(Zα/2+Zβ)^2*σ²/δ²,取α=0.05,β=0.2,计算得每组需260人;◦ 关注字节技术公众号“字节跳动数据团队”,学习真实AB测试案例(如“推荐算法优化实验”)。• 题型分布:SQL编程题(40%)、AB测试方案设计(30%)、数据洞察题(30%);◦ 牛客网“字节跳动SQL真题”(如“统计用户7日留存”“广告投放ROI计算”)。

2501_91651594的博客 1107

超详细!一次性搞懂手写Promise全过程

手写promise超详细步骤,帮助大家理解每一步代码的含义

qq_41852789的博客 1万+

carsim与simulink联合仿真学习笔记(二)——使用C-class车模做driver model仿真(5 driver sensors)

Driver model 在carsim的Simulink库中自带外部驾驶员模型,打开后如图所示: 然后打开carsim中对应的数据集,如图所示: 具体仿真步骤不在赘述,注意到这里选择的是E-Class车模,那么如果我想选择C-Class车型进行仿真呢?点三角选择车型可以看到: 马赛克部分是我后来建的,如过没有使用过是没有马赛克部分的。那么既然这里没有C-class,又该怎么办呢? 创建C-...

xufuqiang2017的博客 4116

ES6手写Promise

使用ES6 class语法实现简易版的手写Promise 实现 then 链式调用、catch、finally、和静态方法resolve,reject,注释清晰,逻辑清晰

ruan479118658的博客 522

UFS 3.1协议分析(第五章) -- UFS协议栈

ContentsUFS顶层架构应用层UFS命令集UFS 设备管理器UFS任务管理器传输层互连层 UFS顶层架构     UFS基于SCSI SAM架构模型定义了一个完整的协议栈,从上到下依次为应用层、传输层、数据链路层、物理层。UFS使用MIPI联盟的UniPro作为数据链路层和MIPI的M-PHY作为物理层,两者合起来称之为互连层(UFS InterConnect Layer) 应用层     应用层包括UFS命令集、设备管

Frank_sample的专栏 7369

将Windbg附加到软件进程上排查异常闪退的问题

使用Windbg和Process Explorer排查因为内存泄漏导致的软件异常闪退问题。

dvlinker的技术专栏 1万+

手写Promise【03】-实现then方法多次调用与链式调用

1. then 方法的多次调用 我们在定义成功successCallback和失败failCallback的回调的时候,只定义了一个值,没有考虑到 then 方法被多次在异步中调用的情况,所以在这里应该将成功和失败的回调定义成为一个可收纳多个值的东西–数组。 successCallback = []; failCallback = []; 所以 then 方法中的回调存储也随之改变: this.successCallback.push(successCallback); this.failCallback

BLUEHEART 1783

使用 MATLAB/Simulink 构建一个基于FOC控制的PMSM矢量控制仿真模型

本教程详细介绍了基于Simulink的永磁同步电机(PMSM)磁场定向控制(FOC)仿真建模过程。主要内容包括:PMSM电机参数设置、Clarke/Park变换模块设计、电流环PID控制器构建、SVPWM调制实现等关键步骤。教程提供了完整的建模流程、参数配置建议和仿真调试方法,并给出了PID整定技巧和进阶优化方向。通过该模型,可深入理解PMSM矢量控制原理,掌握高性能电机控制系统的建模技术,为伺服系统、电动汽车驱动等应用领域提供仿真基础。教程还推荐了使用PIDTuner工具进行参数优化,并提出了加入负载扰动

amy_mhd的博客 644

如何在JavaScript中实现链式调用(chaining)?

如何在JavaScript中实现链式调用(chaining)?

商务合作欢迎私信我 2万+

基于单片机设计的智能消防排烟窗控制系统_422

随着城市化进程的不断加快,高层建筑、大型商业综合体以及地下空间的数量迅速增加,建筑内部结构日趋复杂,一旦发生火灾,烟雾和有毒气体往往比明火更具威胁性。大量研究表明,在火灾事故中,人员伤亡的主要原因并非直接烧伤,而是由于吸入烟雾及一氧化碳等有毒气体导致窒息。因此,如何在火灾初期快速排烟、降低有害气体浓度,并及时进行预警,成为现代消防系统设计中的关键问题。传统的消防排烟系统多依赖人工操作或简单的联动控制方式,存在响应滞后、自动化程度低、信息反馈不及时等问题。在实际应用中,当火灾发生时,如果不能第一时间开启排烟窗

370

海思3559av100平台lan9500模块调试记录

1. 前言 通过USB2.0接口扩展一路百兆虚拟网口 2. 配置lan9500驱动 make ARCH=arm64 menuconfig 开启LAN95XX驱动,编译进内核 保存内核配置 3. 编译内核 make ARCH=arm64 CROSS_COMPILE=aarch64-himix100-linux- uImage -j 20 cd ../../arm-trusted-firmware/arm-trusted-firmware ./mk.sh cp ...

jzwjzw19900922的博客 908

promise链式调用_纯手写 Promise,由浅入深

本文原载于 SegmentFault社区作者:Yxaw现在很多面试也都要求我们有手动造轮子的能力,所以本篇文章我会以手动实现一个 promise 的方式来发掘一下 Promise 的特点。简单版Promise首先我们应该知道 Promise 是通过构造函数的方式来创建的 (new Promise( executor )),并且为 executor 函数 传递参数:functionPr...

weixin_39561004的博客 697

企业微信开发007_域名主体校验未通过,需配置备案主体与当前企业主体相同或有关联关系的域名_企业内部自建应用开发_配置可信域名_回调URL_可信IP---企业微信开发009

因为我这个企业微信是,已经注册了服务商了,所以我又注册了一个不是服务商的测试企业,没有实名认证的,去试了试。而且,网络上找的教程,都是不够详细的,还是会碰到各种各样的问题,记录下来,为后来者提供便利。首先我用natapp.cn 申请了一个免费的域名,然后去,一个,企业微信上去配置,注意。我这个域名,的主体,可能是域名服务商,比如阿里域名 等等的 不是一般的企业域名。我这个企业微信,是开通了服务商的,企业微信,右上角有服务商管理后台的。到时候,直接用,他们自己企业注册的域名,已经备案的再去尝试,

添柴程序猿的专栏 1694

【源码】手写实现一个Promise

使用typescript实现一个promise

有趣愉悦的学习冒险 1103

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

美团经典面试题解析 —— 如何手写一个Promise

前言 手写实现Promise是一道经典的前端面试题。比如在美团,Promise几乎就是必考题,在其它互联网一线大厂也是高频题目。 Promise的实现相对比较复杂,考虑的逻辑也比较多,下面带着大家逐一分析,找到其关键点、以及如何手写一个Promise。 (本文实现遵循promise/A+规范) 1. Promise 基本结构 我们知道实例化Promise对象时传入一个函数作为执行器,有两个参数(resolve和reject)分别将结果变为成功态和失败态。 据此我们可以写出基本结构: ..

欧阳的技术博客 1万+

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

手写一个promise用法_手写实现一个完整的Promise

考虑到了es6的promise的一些细节, 以下代码实现的promise与es6标准promise的行为95%以上相似,用于帮助大家更好的理解promise/*** 定义MyPromise的三种状态常量*/const PENDING = 'pengding'const FULFILLED = 'fulfilled'const REJECTED = 'rejected'/*** 判断是某个变量否为f...

weixin_40001025的博客 698

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

手写一个promise用法_手写一个Promise笔记

手写Promise感觉还是挺常见的,这里记录下自己构建整个Promise的过程,主要参考的是后盾人Promise教程,记录下看完之后的笔记和个人的思考。Promise的基本知识Promise包含pending等待,fulfilled成功,rejected拒绝三种状态,当时pending状态的时候可以转换为成功/拒绝状态,并且转换后不能再转换。一个promise必须有一个then方法,then方法接...

weixin_39603492的博客 276

最最最通俗易懂的promise手写系列(二)- 链式调用

前言 上一次我们写完了Promise的基础功能,明白了promise为何能在任务成功的时候,调成功的回调函数,为何在任务失败的时候调失败的回调函数.今天就把最麻烦的promise链式调用给搞定吧. 附上上篇文章的链接:最最最通俗易懂的promise手写系列(一) 再附上上次的代码吧,以免翻来翻去麻烦. function Promise(executor) { let self ...

weixin_34293059的博客 819

从零手写一个Promise

手写一个promise 分五步走 解决基本状态,即Promise三个状态pending, fulfilled, rejected的转换 解决then方法 支持异步操作 支持链式调用 all和race 1. 解决基本状态 看一段promise代码 const promise = new Promise((resolve, reject) => { con...

zmjのblog 427

手写Promise

按照Promises/A+规范,手写一个Promise

nightwishh的博客 648

面试官:请手写一个Promise

面试官:请手写一个Promise?(开门见山)我:既然说到Promise,那我肯定得先介绍一下JavaScript异步编程的发展史吧,这样就理解为啥Promise会出现以及Promise解决了什么问题了吧。阶段一:回调函数阶段二:事件发布/订阅模型...面试官:我不关心什么异步编程发展史(不耐烦),这年头谁都知道Promise是解决了回调地狱的问题,我关心的是你的编码能力,你直接,直接写!!!我:好吧!(其实手写代码才是我的强项,嘻嘻!因为promise在EventLoop。

web全栈开发的博客 220

手写Promise 功能

手写Promise源码 思路 1、根据Promise最初的语法,定义MyPromise 2、传入函数能立即执行 3、传入的函数能调用类方法,在执行resolve的时候能接受resolve传入的成功值,在执行resolve的时候能接受失败的原因 4、在执行resolve活reject的时候,需要将将等待改成对应的状态,一旦改变当前承诺不能再变: ​ pending ==> fulfilled 等待 =》改成成功 ​ pending ==> rejected 等待 =》改成失败 ​ 由

Start的小笔记 246

带大家如何实现一个手写 Promise

带大家实现一个自定义promise

明平姚的博客 589

方法 手写promise_JS探索-手写Promise

无意间在知乎上刷到Monad这个概念,去了解了一下,前端的Promise就是一种Monad模式,所以试着学习一下手写一个Promise.本文内容主要参考于只会用?一起来手写一个合乎规范的Promise​www.jianshu.comPromise是什么所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可...

weixin_42516657的博客 208

手写Promise,通过Promise/A+的872个测试

github 博客 Promise的声明 当我们使用Promise的时候,通常都是new Promise((resolve, reject) => {})。 因此我们可以看出: Promise是一个类; Promise类的构造函数的第一个参数是函数,这个函数叫处理器函数(executor function); 而在处理器函数中,有了两个参数:resolve和reject 当异步任务顺利完成且返回结果值的时候,我们会调用resolve函数; 当异步任务失败且返回失败原因(通常是一个错误对象).

OUDUIDUI的博客 376

带你手写 Promise,别再死记硬背了!!!

带你手写 Promise,别再死记硬背了!!!

weixin_43822185的博客 996
上一篇: Vue 中 mixin 混入用法简述
下一篇: Vue的响应式原理及实现
JasoncodeQvQ
博客等级 码龄7年 458粉丝 97原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值