promise的实现(如何手写一个promise)(下)

6 篇文章 0 订阅

接上篇 promise的实现(如何手写一个promise)

实现promise的链式调用

第一个例子
在这里插入图片描述
这是第一个例子,可以看到,promise的链式调用就是 可以.then().then().then()…这样一直调用下去。说明, .then() 执行完后会返回一个promise。 并且上一个.then返回的值会被resolve然后传给下一个then。

第二个例子
在这里插入图片描述
如果上一个.then你没有手动给一个返回值,那么就会将undefined传递给下一个.then

class Promise{
	constructor(executor){
		this.state = 'pending'
		this.value = undefined
		this.reason = undefined
		this.FulfilledCallbacks = []
		this.RejectedCallbacks = []
		let resolve = value=>{}
		let reject = reason =>{}
		try{
			executor(resolve,reject)
		}catch(err){
			reject(err)
		}
	}
	then(onFulfilled,onRejected){
		var promise2 = new Promsie((resolve,reject)=>{
			if(this.state == 'pending'){
				this.FulfilledCallbacks.push(onFulfilled)
				this.RejectedCallbacks.push(onRejected)
			}
			if(this.state === 'fulfilled'){
				// 由上面分析可知,.then执行过程中,你可能会手动返回一个东东
				let x = onFulfilled(this.value)  
		// 用一个resolvePromise来处理手动返回的x和内部自动返回的promise2
				resolvePromise(promise2,x,resolve,reject)
			}	
			if(this.state === 'rejected'){
				let y = onRejected(this.reason)
				resolvePromise(promise2,y,resolve,reject)
			}

		})
		return promise2
	}
}

看来resolvePromise决定了promise2的状态,那这个resolvePromise要做什么事情呢? 我们先来捋捋。

  • 返回一个普通值,这个普通值nextValue会直接传递给then
    看到这里,你想到了nextValue是怎么传递给then的吗?
    哈哈,我们注意到
    onFulfilled(this.value)
    那么,毫无疑问,nextValue就是这里的this.value。而this.value是当前promise2的value。 现在,我们就知道了,resolvePromise的任务就是resolve 当前promise2的,这样下一个then调用的时候就能获得promise2的value。

  • 返回的是一个promise,
    比如
    在这里插入图片描述
    显然,返回的是一个promise的话,会先等这个promise先resolve完成,再把这个promise的值想办法给到promise2的value。
    那么问题来了, promise2怎么样才能拿到这个promise( x )的value呢?还是这句话
    then(onFulfilled,){... onFulfilled(this.calue)}
    那么我们就主动调用x.then呗
    ,

function resolvePromise(promise,x,resolve,reject){
	if(x === promise){
		return reject(new TypeError('Chaining cycle detected for promise'))
	}
	// 防止多次调用
	let called;
	if(x != null && (typeof x == 'object'||typeof x == 'function')){
		try{
			let then = x.then
			// 如果then是函数,就说明x是promise
			then.call(x, y=>{ 
							if(called) return
							called = true
							//resolve(y)
							resolvePromise(promise2,y,resolve,reject)
						},err=>{
						// 无论先调用了resolve,还是reject,另一再调用也没用
							if(called) return
							called = true
							reject(err)
						})	
		}catch(err){
			reject(err)
		}		
	}else{
		// x是普通值
		resolve(x)
	}
}
补充
  • 如果onFulfilled不是函数则忽略onFullfilled
  • then里的回调函数是异步调用的,我们权且用setTimeout来模拟不是
    在这里插入图片描述
class Promise{
   
   then(onFulfilled,onRejected){
   	 onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (value) => {return value}
   	 onRejected = typeof onRejected === 'function' ? onRejected:  throw err
   	var promise2 = new Promise((resolve,reject)=>{
   			if(this.state === 'pending'){
   					this.fulfilledCallbacks.push(()=>{
   						setTimeout(()=>{
   								let x= onFulfilled(this.value)
   								resolvePromise(promise2,x,resolve,reject)
   						},0)
   					})
   					this.rejectedCallbacks.push(()=>{
   						....
   					})
   			}		
   			if(this.state === 'fulfilled'){
   				setTimeout(()=>{
   						let x= onFulfilled(this.value)
   						resolvePromise(promise2,x,resolve,reject)
   				},0)
   			}
   			if(this.state == 'rejected'){
   			  	setTimeout(()=>{
   			  			try{
   							let x = onRejected(this.value)
   							resolvePromise(promise2,x,resolve,reject)
   						}catch(err){
   							reject(err)
   						}
   			  	},0)	
   			}
   	})
   	return promise2
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值