手写promise 草稿

			const pending = 'PENDING'
			const resolved = 'RESOLVED'
			const rejected = 'REJECTED'
			
			const resolvePromise = (promis2,x,resolve,reject)=>{
				// 判断x的值是不是和promise 是不是同一个,如果是同一个就是自己等待自己,自己不会成功也不会失败
				if(promis2 === x) {
					return reject(new TypeError('chaining cycle detected for promise #<Promise>'))
				}
				if ((typeof x === 'object' && x !== null ) || typeof x === 'function') {
					let called
					try{
						let then = x.then  // 取then方法,有可能这个then方法是通过defineProperty定义的,取then的时候可能报错
						if(typeof then === 'function'){  //判断当前有then方法,认为返回的是一个promise
							then.call(x,y =>{
								if(called){
									return
								}
								called = true
								resolvePromise(promis2,x,resolve,reject) //采用promise的成功结果向下传递,y 可能还是promise,直到解析出来的结果是一个普通值
							},r=>{
								if(called){
									return
								}
								called = true
								reject(r)  //采用失败的结果向下传递
							}) //保证不用再次去then的值
						} else {
							resolve(x)  // 说明x 是一个普通函数,直接成功即可
						}
					}catch(e){
						if(called){
							return
						}
						called = true
						reject(e)
					}
				} else {
					// x 是普通值
					resolve(x)  // 直接让promise 成功
				}
			}
			class MyPromise{
				constructor(executor) {
					// executor 执行器,特点,默认会立即执行
				    this.status = 'PENDING'
					this.value = undefined //成功时候的值
					this.reason = undefined // 失败时候的值
					this.onFufiledCallBacks = []   // 保存成功的回调
					this.onRejectedCallBacks = []  //保存失败的回调
					const resolve = (value)=>{
						if (this.status === pending) {
							this.status = resolved
							this.value = value
							this.onFufiledCallBacks.forEach(fn => fn(value))
						}
					}
					const reject = (reason)=>{
						if (this.status === pending) {
							this.status = rejected
							this.reason = reason
							this.onRejectedCallBacks.forEach(fn => fn(reason))
						}
					}
					// 内部也可能抛错,所以使用try catch
					try{
						executor(resolve,reject) // executor 执行器,特点,默认会立即执行
					}catch(e){
						reject(e)  // 执行时发生的异常,等价于调用了失败方法
					}
					
				}
				// 原型上公用的方法,定义到当前实例上才能在原型上拿到	// 看这个属性是否在原型上拿到,看属性是否公用
				then(onFufiled, onRejected){
					onFufiled = typeof onFufiled === 'function'? onFufiled : data => data
					onRejected = typeof onRejected === 'function' ? onRejected: err => {
						return err
					}
					
					let promis2 = new MyPromise((resolve,reject)=>{  //这里new Promise 会立即执行,new出的promise是自己定义的
						// 处理同步
						if(this.status === resolved){
							setTimeout(()=>{
								try{
									//x 可能是普通值,也可能是promise
									let x = onFufiled(this.value)
									// 判断x的值
									resolvePromise(promis2,x,resolve,reject)
								}catch(e){
									reject(e)
								}
							},0)
						
						}
						if(this.status === rejected){
							setTimeout(()=>{
								try{
									let x = onRejected(this.reason)
									// 判断x的值
									resolvePromise(promis2,x,resolve,reject)
								}catch(e){
									reject(e)
								}
							},0)
						}
						
						// 如果是异步情况
						if(this.status === pending){
							// 异步情况率先订阅
							this.onFufiledCallBacks.push(()=>{
								setTimeout(()=>{
									try{
										let x = onFufiled(this.value)
										resolvePromise(promis2,x,resolve,reject)
									}catch(e){
										reject(e)
									}
								},0)
							})
							this.onRejectedCallBacks.push(()=>{
								setTimeout(()=>{
									try{
										let x = onRejected(this.reason)
										resolvePromise(promis2,x,resolve,reject)
									}catch(e){
										reject(e)
									}
								},0)
							})
						}
					})
					
					return promis2
				}
			}
			
			Promise.defer = Promise.deferred = function(){
				let dfd = {}
				dfd.promise = new Promise((resolve,reject)=>{
					dfd.resolve = resolve
					dfd.reject = reject
				})
				return dfd
			}
			
			module.exports = Promise
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值