手写Promise

Promise.js 

class Promise {
	//构造方法
	constructor(executor) {
		this.PromiseState = 'pending';
		this.PromiseResult = null;
		//声明属性
		this.callbacks = [];
		//保存实例对象this的值
		const self = this;  //self,_this,that
		
		//resolve函数
		function resolve(data){
			//判断状态,保证promise状态只能更改一次
			if(self.PromiseState !== 'pending') return;
			
			//1.修改对象状态(promiseState)
			self.PromiseState = 'fulfilled';//resoled	
			//2.设置对象结果值(promiseResult)
			self.PromiseResult = data;
			//如果self改为this状态不变化,因为this指向全局window对象,可以用
			//console.log(this);查看效果
			
			//调用成功的回调函数,处理异步,指定多个回调实现
			setTimeout(() =>{
				self.callbacks.forEach(item => {
					item.onResolved(data);
				})	
			});
		}
		//reject函数
		function reject(data){
			//判断状态
			if(self.PromiseState !== 'pending') return;
			//1.修改对象状态(promiseState)
			self.PromiseState = 'rejected';//resoled	
			//2.设置对象结果值(promiseResult)
			self.PromiseResult = data;
			//执行失败的回调
			setTimeout(() =>{
			self.callbacks.forEach(item => {
				item.onRejected(data);
			})	
			});
		}
		try{
		//同步调用【执行器函数】
		executor(resolve,reject);
		}catch(e){
			//修改promise对象状态为【失败】
			reject(e);
		}
	}
	
	//then方法封装
	then(onResolved,onRejected){
		const self = this;
			//判断回调函数参数
			//onRejected !== 'function',异常穿透报错,解决原理:加默认值
			if(typeof onRejected !== 'function'){
				onRejected = reason => {
					throw reason;
				}
			}
			if(typeof onResolved !== 'function'){
				onResolved = value => {
					return value;
				}
			}
			return new Promise((resolve,reject) =>{
			//封装函数,避免重复代码
			function callback(type){
				try{
					let result = type(self.PromiseResult);
					//判断
					if(result instanceof Promise){
						//如果是promise类型对象
						result.then(v =>{
							resolve(v)
						},r=>{
							reject(r);
						})//v和r相当于html返回的promise对象的resolve与reject数据
					}else{
						//结果的对象状态为成功
						resolve(result);
					}
				}catch(e){
					reject(e);
				}
			}
				
				
			//调用回调函数   PromiseState
				if(this.PromiseState === 'fulfilled'){
					setTimeout(()=>{
						//获取回调函数执行结果
						callback(onResolved);
					})
				}
				if(this.PromiseState === 'rejected'){
					setTimeout(()=>{
						//获取回调函数执行结果
						callback(onRejected());
					})
				}
				//判断pending状态
				if(this.PromiseState === 'pending'){
					//保存回调函数,这点很重要
					this.callbacks.push( {
						onResolved: function(){
							//执行成功回调函数
							callback(onResolved);
						},
						onRejected: function(){
							callback(onRejected);
						}
					});
				}	
		})
	}
	
	//catch方法封装
	catch(onRejected){
		return this.then(undefined,onRejected);
	}
	
	//resolve方法,属于类而不是实例对象,用static
	static resolve(value){
		return new Promise((resolve,reject) => {
			if(value instanceof Promise){
				value.then(v=>{
					resolve(v);
				}, r=>{
					reject(r);
				})
			}else{
				//状态设置成功
				resolve(value);
			}		
		});
	}

	//封装reject方法
	static reject(reason){
		return new Promise((resolve,reject) => {
			reject(reason);
		});
	}
	
	//添加all方法,必须全部成功才成功
	static all(promises){
		//返回结果为promise对象
		return new Promise((resolve,reject)=>{
			//声明变量
			let count = 0;
			let arr = [];
			//遍历
			for(let i=0;i<promises.length;i++){
				//
				promises[i].then(v =>{
					//得知对象的状态时成功的
					//每个promise对象都成功
					count++;
					//将当前promise对象成功的结果,存入到数组中
					arr[i] = v;
					//判断,promise全部成功才修改状态,因为状态只能变一次
					if(count === promises.length){
						//修改状态
						resolve(arr);
					}
				},r => {
					reject(r);
				})
			}
		});
	}

	//添加race方法
	static race(promises){
		return new Promise((resolve,reject) =>{
			for(let i=1;i<promises.length;i++){
				promises[i].then(v =>{
					//修改返回对象的状态为成功
					resolve(v);
				},r =>{
					//修改返回对象的状态为失败
					reject(r);
				})
			}
		})
	}

}







测试代码1:

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title>Promise封装|1-初始结构搭建</title>
	</head>
	<script src="Promise.js"></script>
	<body>
		<script>
			let p = new Promise((resolve,reject) => {
				setTimeout(() =>{
				//resolve('OK');
				reject('err');
				//throw "err";
				},1000)
				
			// 	// reject('err');			
			// 	//抛出异常
			// 	 //throw "throwerror";
			// });
			// let p = new Promise((resolve,reject) => {
			// 	//resolve('ok')
			// 	reject('err');
				
			});
			//因为res返回undefined,所以res状态为成功
			// const res = p.then(value => {
			// 	console.log(value);
			// 	//return 'hello world';
			// 	// return new Promise((resolve,reject) => {
			// 	// 	resolve("promise.success");
			// 	// 	reject("oh no");
			// 	// })
			// 	//抛出异常
			// 	 //throw "FAIL";
			// },reason=>{
			// 	console.warn(reason);
			// 	//throw "FAIL1";
			// });
			// p.then(value => {
			// 	alert(value);
			// },reason=>{
			// 	alert(reason);
			// });//测试多个回调实现
			
			// let res = p.catch(reason =>{
			// 	console.warn(reason);
			// });
			//console.log(res);
			//值传递
			p.then(
			//value =>{
			//	console.log(111);
				//throw 'error';}
				).then(value =>{
				console.log(222);
			}).then(value =>{
				console.log(333);
			}).catch(reason => {
				console.warn(reason);
			})
			
		</script>
	</body>
</html>

测试代码2

<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
	</head>
	<script src="Promise.js"></script>
	<body>
		<script>
			// const p =Promise.reject('error');
			// const p2 = Promise.reject(new Promise((resolve,reject) =>{
			// 	resolve("okt5");
			// }))
			// //const p3 = Promise.resolve(Promise.resolve('oh yeah'));
			// console.log(p);
			// console.log(p2);
			let p1 = new Promise((resolve,reject) => {
				reject('err');
			});
			
			p1.then(value =>{
				console.log(value);
				//console.log(222);
			},reason =>{
				console.warn(reason);
			});
			
			//console.log(333);
			// let p2 = Promise.resolve('666');
			// let p3 = Promise.resolve('success');
			
			//调用all方法
			// let result = Promise.all([p1,p2,p3]);
			
			//调用race方法,p1决定
			// let result = Promise.race([p1,p2,p3])
			// console.log(result);
					
		</script>
	</body>
</html>

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值