手写Promise

手写 Promise

myPromise 基本实现
Promise构造函数接收一个executor (执行) 函数,executor函数执行完同步或异步操作后,调用它的两个参数resolve和reject
Promise有三个状态: pending 等待(进行中)、resolved 成功 、rejected 失败
function myPromise (excutor) {
	var self = this
	// 当前的状态
	self.status = 'pending'
	//  状态为成功时的值
	self.value = null
	//状态为失败时的error 信息
	self.reason = null 
	// 用户触发成功
	function resolve(value) {
	    if (self.status ==  'pending') {
			// 如果执行成功
			self.value = value
			self.status = 'resolved'
		}
	}
	// 用户触发失败
	function reject(reason) {
	   if (self.status ==  'pending') {
			// 如果执行成功
			self.reason = reason
			self.status = 'rejected'
		}
	}
	// 考虑到执行executor的过程中有可能出错,所以我们用try/catch块给包起来,并且在出错后以catch到的值reject掉这个Promise
	try { 
	  executor(resolve, reject) // 执行executor
	} catch(e) {
	  reject(e)
	}
}
myPromise.prototype.then = (onFulfiled, onRejected) => {
	let self = this
	// 根据状态调用函数
	if (self.status == 'resolved') {
		onFulfiled(self.value)
	}
	if (self.status == 'rejected') {
		onFulfiled(self.reason)
	}
}
Promise 异步状态处理 (场景 setTimeout)
function myPromise (excutor) {
	var self = this
	// 当前的状态
	self.status = 'pending'
	//  状态为成功时的值
	self.value = null
	//状态为失败时的error 信息
	self.reason = null 
	// 因为是异步调用 所以需要把callback缓存起来
	self.onFulfilledCallbacks = [] // 成功的回调
  	self.onRejectedCallbacks = [] // 失败的回调
	// 用户触发成功
	function resolve(value) {
	    if (self.status ==  'pending') {
			// 如果执行成功
			self.value = value
			self.status = 'resolved'
			// 遍历储存的回调函数执行
			self.onFulfilledCallbacks.forEach((item, i) => { return item.value })
		}
	}
	// 用户触发失败
	function reject(reason) {
	   if (self.status ==  'pending') {
			// 如果执行成功
			self.reason = reason
			self.status = 'rejected'
			// 遍历储存的回调函数执行
			self.onRejectedCallbacks.forEach((item, i) => { return item.reason })
		}
	}
	// 考虑到执行executor的过程中有可能出错,所以我们用try/catch块给包起来,并且在出错后以catch到的值reject掉这个Promise
	try { 
	  executor(resolve, reject) // 执行executor
	} catch(e) {
	  reject(e)
	}
}
myPromise.prototype.then = (onFulfiled, onRejected) => {
	let self = this
	// 根据状态调用函数  无法链式调用
	// if (self.status == 'resolved') {
	// 		return myPromise((resolve, reject) => {
	// 			 onFulfiled(self.value)
	// 		})
			
	// 	}
	// 	if (self.status == 'rejected') {
	// 		return myPromise((resolve, reject) => {
	// 			onRejected(self.reason)
	// 		})
	// 	}
	// 	// **比如 setTimeout 异步 存储需要执行的方法**  
	// 	if (self.status == 'pending') {
	// 		return myPromise ((resolve, reject) => {
	// 			self.onFulfilledCallbacks.push(onFulfiled)
	// 			self.onRejectedCallbacks.push(onRejected)
	// 		})
	// 	}
	
	// 根据状态调用函数 升级链式调用
	// then 中没有传成功或者失败的回调函数, 所以做容错处理
	onFulfiled = onFulfiled typeof 'function' ? onFulfiled : (data) => { return data }
	onRejected = onRejected typeof 'function' ? onRejected : (err) => { throw '王新鹏抛出的错误:' +  err }
	if (self.status == 'resolved') {
		return myPromise((resolve, reject) => {
			try {
				let x = onFulfiled(self.value)
				x instanceof Promise ? x.then(resolve, reject) : resolve(x) 
			} catch {
				reject(err)
			}
		})
		
	}
	if (self.status == 'rejected') {
		return myPromise((resolve, reject) => {
			try {
				let x = onRejected(self.reason)
				x instanceof Promise ? x.then(resolve, reject) : resolve(x) 
			} catch {
				reject(err)
			}
		})
	}
	// **比如 setTimeout 异步 存储需要执行的方法**  
	if (self.status == 'pending') {
		return myPromise ((resolve, reject) => {
			// self.onFulfilledCallbacks.push(onFulfiled)
			// self.onRejectedCallbacks.push(onRejected)
  			self.onFulfilledCallbacks.push(() => {
		        let x = onFulfilled(self.value)
		        x instanceof Promise ? x.then(resolve, reject) : resolve(x)
	      	})
	      	self.onRejectedCallbacks.push(() => {
		        let x = onRejected(self.reason)
		        x instanceof Promise ? x.then(resolve, reject) : resolve(x)
	      	})
		})
	}
}
// 只给then传失败的回调函数就是Promise 的catch 方法
myPromise.prototype.catch = (fn) => {
	return this.then(null, fn)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值