手写一个简易的Promise

;(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资料:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值