手写一个简易的Promise

本文深入解析Promise的工作原理,从头开始实现一个简单的Promise类,包括其构造函数、状态管理、错误处理以及链式调用机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

;(function () {

	class Promise {

		const status = {
			pending: 0,
			fulfilled: 1,
			rejected: 2
		}

		constructor (executor) {
			//初始状态
			this._status = status.pending;
			this._value = null;   //记录resolve函数传入的值
			this._error = null;		//记录reject函数传入的值

			//收集成功状态要执行的函数
			this.resolvedArr = [];
			//收集失败状态要执行的函数
			this.rejectedArr = [];

			this._handler(executor);

		}

		//判断value有没有then函数,并且将then函数返回
		_getThen (value) {
			let type = typeof value;
			if (value && (type === 'object' || type === 'function')) {
				let then;
				if (then = value.then) {
					return then;
				}
				return null;
			}
		}


		//接收外部传入的函数,调用外部传入的函数
		_handler (executor) {
			let done = false;  //就是让函数值执行一次
			executor((value) => {
				if (done) return;
				done = true;

				//value有没有then函数,有then函数的话必须等value的then函数执行完毕之后才能调用_resolve函数
				let then = this._getThen(value);
				if (then) {
					//拿到对象的then之后,怎么知道这个promise对象完成了呢
					//在then函数上注册成功和失败函数就可以了
					return this._handler(then.bind(value)); 
				}

				this._resolve(value);
			}, (error) => {
				if (done) return;
				done = true;

				//error有没有then函数,有then函数的话必须等value的then函数执行完毕之后才能调用_resolve函数
				let then = this._getThen(error);
				if (then) {
					//拿到对象的then之后,怎么知道这个promise对象完成了呢
					//在then函数上注册成功和失败函数就可以了
					return this._handler(then.bind(error));
				}
				this._reject(error);
			})
		}

		_resolve (value) {
			setTimeout(() => {
				//把状态改为成功
				this._status = status.fulfilled;
				this._value = value;

				//执行所有注册的成功的函数
				this.resolvedArr.forEach(item => item(this._value));
			})
		}

		_reject (error) {
			setTimeout(() => {
				//把状态改为失败
				this._status = status.rejected;
				this._error = error;

				//执行所有注册的失败的函数
				this.rejectedArr.forEach(item => item(this._error));
			})
		}

		//收集注册成功状态或失败状态要执行的函数
		_done (resolvedFunc, rejectedFunc) {
			resolvedFunc = typeof resolvedFunc === 'function' ? resolvedFunc : null;
			rejectedFunc = typeof rejectedFunc === 'function' ? rejectedFunc : null;
			//pending阶段收集
			if (this._status === 0) {
				if (resolvedFunc) this.resolvedArr.push(resolvedFunc);
				if (rejectedFunc) this.rejectedArr.push(rejectedFunc);
			} else if (this._status === 1 && resolvedFunc) {   //直接执行
				resolvedFunc(this._value);
			} else if (this._status === 2 && rejectedFunc) {   //直接执行
				rejectedFunc(this._error);
			}
		}

		//非链式调用写法
		// then (resolvedFunc, rejectedFunc) {
		// 	this._done(resolvedFunc, rejectedFunc);
		// }
		
		//链式调用写法
		then (resolvedFunc, rejectedFunc) {
			return new Promise((resolve, reject) => {
			  this._done((value) => {  //收集成功执行函数
					if (typeof resolvedFunc !== 'function') {
						return resolve(value);
					}
					resolve(resolvedFunc(value));
				}, (error) => {  //收集失败执行函数
					if (typeof rejectedFunc !== 'function') {
						return reject(error);
					}
					reject(rejectedFunc(error));
				});
			})
			
		}

	}

	window.Promise = Promise;

})();

其他的一些Promise资料:

### 实现支持并发执行的自定义Promise函数 为了创建一个能够并行处理多个异步操作的 `Promise` 函数,可以借鉴 JavaScript 中现有的模式和技术。具体来说,可以通过构建一个类似于 `Promise.all()` 的功能来管理一组并发的任务。 #### 设计思路 核心概念在于维护一个池(pool),该池负责跟踪当前正在运行的请求数量以及待处理的任务列表。每当有新的任务加入时,如果未达到最大并发数,则立即启动;否则等待已有任务完成后再启动新任务。这种方式既能保证高效利用资源又不会造成过多的同时连接。 #### 关键技术点 - 使用 `Promise` 对象封装每一个单独的操作。 - 利用 `async/await` 结合 `try/catch` 来简化错误处理逻辑[^1]。 - 应用闭包特性保存上下文环境中的变量状态。 - 通过事件监听机制监控已完成的工作项,并据此决定何时发起下一批次的新工作项。 #### 代码实现 下面是一个简单的基于上述原理的手写版 `concurrentPromises` 方法: ```javascript function concurrentPromises(tasks, limit) { let executing = []; const makeRequest = async (task) => { try { await task; } catch(error){ console.error('Error occurred:', error); } finally { executing.splice(executing.indexOf(task), 1); if (tasks.length > 0) { startNext(); } } }; const startNext = () => { while (executing.length < limit && tasks.length > 0) { const promiseTask = tasks.shift().promiseFunction(); // Assume each item has .promiseFunction() executing.push(promiseTask); makeRequest(promiseTask); } }; return new Promise((resolve) => { startNext(); if (executing.length === 0) resolve(); for(const p of executing){ p.then(() => { if (executing.length === 0 && tasks.length === 0) resolve(); }); } }); } ``` 此段代码实现了对给定任务集合按指定的最大并发度(`limit`)进行调度的功能。它会持续监测已提交的任务进度,在条件允许的情况下不断向系统注入新的作业直到整个队列清空为止。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值