Promise的实现原理(三)

Promise的实现原理(三)

1.Promise 实现原理

1.1 Promise 实现原理之链式调用

1.1.1 基础用法

const p =new Promise((resolve,reject)=>{
	resolve('成功')//这里得成功会调用下一个.then里的res回调函数
	reject('失败')//这里得失败会调用下一个.then里的err回调函数
})
const p1 = p.then(res=>{
	return res // 这里return值会在下一个.then中data回调中
},(err)=>{
return err //这里return值也会在下一个.then中data回调中
})
p1.then((data)=>{
	console.log('data',data);
},(err)=>{
	// 这里得err 是报的上一个.then 执行中的错误 例如:p.then((res)=>{return new Error('错误')})
})

1.1.1.2 实现思路
问题1:为什么可以连续(点).then,什么东西可以(点).then?
答案:无非就是在实现then 方法的时候 在返回一个新的Promise

问题2:当前then的中数据,如何传到下一个Promise的then 中?
答案:取到当前的值,调用新的Promise 的resolve 方法,就是值传到下一个Promise的then中了么;

1.1.1.3 具体实现

class Mypromise {
	// executor 执行者,也就是调用方传过来的函数,他是立即执行的
	constructor(executor){
		// 状态设置,因为promise 的状态是一旦改变就不允许返回的,我们已0为初始化状态
		this.stateus= 0;
	
		// 异步的核心思想就是发布订阅,首先创建两个数组,分别来存储成功回调,以及失败的回调
		this.successArray = [];
		this.errorArray   = [];
		
		// executor又有两个回调函数,一个成功的函数resolve,一个失败的状态reject,首先定义这两个函数
		// 使用者传回成功的value值
		const resolve = (value)=>{
			// 因为promise 的状态是不可逆的,因此这里需要更改status 的状态值
			// 用户在.then 的时候,需要在把value值返回给用户,因此要把value暂存一下
			this.successValue = value;
			this.stateus=1;

			// 循环调用.then时的回调函数
			this.successArray.forEach(fn=>fn())

		}
		// 使用者传回失败的value值
		const reject= (value)=>{
			// 同上
			this.errorValue = value;
			this.stateus=2;

			// 循环调用.then时的回调函数
			this.successArray.forEach(fn=>fn())
		
		}
		executor(resolve,reject);

	}
	// 新定义的方法,处理链式调用
	resolvePromise(p2,x,resolve,reject){
		// 这里的x 就是then函数中的res(成功回调函数)回调函数的return 值,它可能是一个普通类型,可					能又是一个promise
		if(typeof x === 'object'&&x!==null){
			if(typeof x ==='function'){
				// 如果他是一个promise 我们取到它的值
				const then = x.then;
				if(then){
				//这里的x 就是return 出来的promise
					then.call(x,(data)=>{
						//这里的data可能是个普通值又有可能是个promise
						this.resolvePromise(p2,data,resolve,reject)
					},(error)=>{
						reject(error)
					})
				}
			}
		}else{
		// 如果是个普通值,我们就把它返回出去,不管成功还是失败
			resolve(x)
		}
	}
	// success,error是用户传过来的回调函数
	then(success,error){
	// 新增代码,修改原来的then 方法
	const p2 = new Mypromise((resolve,reject)=>{
			// 因为promise 是一旦成就不允许失败的,或者一旦失败不允许成功,所以这里要判断一下
			if(this.stateus===1){
				// 因为promise中的then 是微任务,所以这里也行要改造一下,我这里用一个宏任务代替settimeout
				setTimeout(()=>{
				// 这里还应该加一些try catch 的,我这里就省略了
				// 如何把当前的值,传给下一个new promise 中的then中呢;实现如下
					const x = success(this.successValue);
				// 接下来我们单独写一个方法来处理这部分
					this.resolvePromise(p2,x,resolve,reject)
				},0)
				
			}
			if(this.stateus===2){
				setTimeout(()=>{
				// 这里还应该加一些try catch 的,我这里就省略了
				const x = error(this.errorValue);
				this.resolvePromise(p2,x,resolve,reject)
				},0)

			}
	
			// 当用户调用.then 时,我们的status 处于0的状态
			if(this.stateus===0){
				// 这里我们push 一个函数,是因为我们可以在这个函数中可以扩展一些东西
				setTimeout(()=>{
					this.successArray.push(()=>{
					// 这里还应该加一些try catch 的,我这里就省略了
						const x = success(this.successValue);
						this.resolvePromise(p2,x,resolve,reject)
					});
				},0)

				setTimeout(()=>{
					this.errorArray.push(()=>{
					// 这里还应该加一些try catch 的,我这里就省略了
						const x = error(this.errorValue);
						this.resolvePromise(p2,x,resolve,reject)
					});
				},0)

			}
		})
	return p2 //此时return 出去一个新的Promise,即可实现链式调用
	}
}

到这里里基本上一个简版的Promise 完成了。

Promise的实现原理(四)写le一些Promise.all 以及Promise.race的基本实现;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值