从深入理解到自定义Promise--下篇

本文上篇链接: 从深入理解到自定义Promise–上篇


定义整体结构

/*Promise构造函数*/
function MyPromise(excutor) {

}

/*构造方法*/
  /*返回一个指定成功value的promise对象*/
MyPromise.resolve = function (value) {

}
  /*返回一个指定失败reason的promise对象*/
MyPromise.reject = function(reason) {

}
  /*返回一个promise,只有列表中所有的promise都成功才算最终成功*/
MyPromise.all = function(promiseList) {

}
  /*返回一个promise,一旦列表中某个promise解决或拒绝了,返回这个结果*/
MyPromise.race = function(promiseList){

}


/*实例方法*/
  /*为promise指定成功/失败的回调,返回一个新的promise对象*/
MyPromise.prototype.then = function (onResolve,onRejected) {

}
  /*为promise指定失败的回调,返回一个新的promise对象*/
MyPromise.prototype.catch = function(onRejected) {

}


module.exports = MyPromise;

完成构造函数的实现

在构造函数Promise

第一步 同步调用执行器函数 (需要声明resolve,reject函数)

excutor(resolve,reject);

function resolve(data) {};
function reject(data) {};

第二步 设计resolve,reject函数 (调用resolve函数或reject函数时会改变状态)

this.status = "pending";
this.result = null;
//保存实例对象的this值
const that = this;


function resolve(data) {
	//改变实例对象的状态
	that.status = "resolved";
	//改变状态的同时保存结果
	that.result = data;
}
function reject(data) {
	//改变实例对象的状态
	that.status = "rejected";
	//改变状态的同时保存结果
	that.result = data;
}

第三步 完善状态改变方案

//考虑到throw 抛出异常时,状态改变为rejected,改写执行器调用部分为
try {
	excutor(resolve,reject);
} catch(err) {
	reject(err);
}

//考虑到状态只能修改一次,修改函数如下
function resolve(data) {
	if(that.status !== "pending") return;
	//改变实例对象的状态
	that.status = "resolved";
	//改变状态的同时保存结果
	that.result = data;
}
function reject(data) {
	if(that.status !== "pending") return;
	//改变实例对象的状态
	that.status = "rejected";
	//改变状态的同时保存结果
	that.result = data;
}

Promise.then/catch的实现

在实例方法Promise.prototype.then

第一步 调用onResolved,onRejected回调函数

Promise.prototype.then = function (onResolved,onRejected) {
	if(this.status === "resolved") {
		onResolved(this.result);
	}else if(this.status === "rejected") {
		onRejected(this.result);
	}
}

第二步 实现先指定回调函数,后改变状态
目前为止,自定义的promise还不具备先定义回调函数后改状态的能力
解决方法:在构造函数中定义属性callback,在实例方法里面.判断status为pending时,保存回调函数到callback中

构造函数Promise中添加

//添加属性保存回调函数
this.callback = {};

//当回调函数存在,就调用
function resolve(data) {
	//...省略前面代码
	that.callback.onResolved && that.callback.onResolved(data);
}
function reject(data) {
	//...省略前面代码
	that.callback.onRejected && that.callback.onRejected(data);
}

在实例方法Promise.prototype.then中添加

else if(this.status === "pending") {
	this.callback = {
		onResolved,
		onRejected
	};
}

第三步 解决保存回调的缺陷
上述代码保存回调的方法,只是个调用一次then时保存
同一个promise对象保存不同回调时,保存的是最后一次的回调
构造函数Promise中修改

//添加属性保存回调函数
this.callback = [];

//遍历数组调用
function resolve(data) {
	//...省略前面代码
	that.callback.forEach(item => {item.onResolved(data)})
}
function reject(data) {
	//...省略前面代码
	that.callback.forEach(item => {item.onRejected(data)})
}

在实例方法Promise.prototype.then中修改

else if(this.status === "pending") {
	this.callback.push({
		onResolved,
		onRejected
	});
}

第四步 实现then方法返回结果

Promise.prototype.then = function (onResolved,onRejected) {

	const that = this;
	
	//返回的结果必须的promise对象
	return new Promise((resolve,reject) => {
		//封装函数
		function callback(fn){
			try{
				//先拿到结果,然后按结果分类处理
				let result = fn(that.result);
			
				//结果如果是promise对象
				if(result instanceof Promise) {
					result.then(value => {
						resolve(value);
					},reason => {
						reject(reason);
					})
				}else {
					resolve(result);
				}
			}catch(err) {	//如果是抛出异常
				reject(err)
			}
		}
	
		//如果状态是resolved
		if(this.status === "resolved") {
			fn(onResolved);
		}

		//如果状态是rejected
		else if(this.status === "rejected") {
			fn(onRejected);
		}

		//如果状态是pending
		else if(this.status === "pending") {
			this.callback.push({
				onResolved,
				onRejected
			});
		}
	})
}

第五步 解决异步情况,返回结果的状态是pending情况

//如果状态是pending
return new Promise((resolve,reject) => {
	//...
	else if(this.status === "pending") {
		this.callback.push({
			onResolved:function(){
				fn(onResolved);
			},
			onRejected:function(){
				fn(onRejected);
			}
		});
	}
}

添加catch方法
Promise.prototype.catch中添加
第一步 实现catch功能

Promise.prototype.catch = function (onRejected){
	return this.then(null,onRejected);
}

Promise.prototype.then中添加
第二步 实现异常穿透 和 值传递

Promise.prototype.then= function (onResolve,onRejected){
	const that = this;

	if(typeof onResolved !== "function") {
		onResolved = value => value;
	}

	if(typeof onRejected !== "function") {
		onRejected = reason => {
			throw reason;
		}
	}

	//...

Promise.resolve/reject的实现

…后续补充

Promise.all/race的实现

…后续补充

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值