手写一个Promise

// 手写一个promise

// 思路
// 1、 他是一个类, 传递一个执行器进去, 这个执行器会立即执行
// 2、 有3种状态 成功fulfilled 失败rejected 等待pending
// 3、 resolve reject是用来改变状态的,可以通过调用来更改状态,可接受参数作为执行的结果
// 4、处理异步操作
// 5、处理多次then的调用
// 6、实现链式调用 2个点,then返回promise对象 value是上一次返回的值
// 7、捕获构造器函数错误和成功失败函数的错误
// 8、then允许不传递参数
// 9、promise不允许返回实例本身
// 10、静态方法all方法的实现
// 11、静态方法resolve方法的实现
// 12、finally方法的实现
// 13、catch方法的实现
// const p = new Promies((resovle, rejuect) => {

// })
// p.then((value)=>{},(error)=>{}) then可以多次调用
// .then((value)=>{},(error)=>{})
// .then((value)=>{},(error)=>{})

const PENGDING = 'pengding'
const REJECTED = 'rejected'
const FULFILLED = 'fulfilled'

const resolvePromise = (promise2, returnValue, resolve, reject) => {
	if (promise2 === returnValue) {
		return reject(new Error('不能返回当前promise实例'))
	}
	if (returnValue instanceof MyPromise) {
		// 返回promise
		returnValue.then(resolve, reject)
	} else {
		// 返回常量
		resolve(returnValue)
	}
}

class MyPromise {
	constructor(executor) {
		try {
			executor(this.resolve, this.reject)
		} catch (e) {
			this.reject(e)
		}
	}
	status = PENGDING
	// 成功之后的值
	value = undefined
	// 失败之后的原因
	resion = undefined
	// 定义成功回调
	successCallback = []
	// 定义失败回调
	errorCallback = []
	// finally方法
	finally = (callback) => {
		return this.then(value => {
			return MyPromise.resolve(callback()).then(() => value)
		}, error => {
			return MyPromise.resolve(callback()).then(() => {
				throw error
			})
		})
	}
	// catch方法
	catch = (failCallback) => {
		return this.then(undefined, failCallback)
	}
	resolve = value => {
		if (this.status !== PENGDING) {
			return
		}
		this.status = FULFILLED
		this.value = value
		// 异步的情况
		// this.successCallback && this.successCallback(this.value)
		// 上面代码优化成多次调用then方法
		while (this.successCallback.length) this.successCallback.shift()()
	}
	reject = resion => {
		if (this.status !== PENGDING) {
			return
		}
		this.status = REJECTED
		this.resion = resion
		// 异步的情况
		// this.errorCallback && this.errorCallback(this.resion)
		// 上面代码优化成多次调用then方法
		while (this.errorCallback.length) this.errorCallback.shift()()
	}
	then(successCallback = v => v, errorCallback = e => {
		throw e
	}) {
		const promise2 = new MyPromise((resolve, reject) => {
			if (this.status === FULFILLED) {
				setTimeout(() => {
					try {
						const returnValue = successCallback(this.value)
						resolvePromise(promise2, returnValue, resolve, reject)
					} catch (e) {
						reject(e)
					}
				}, 0)
			}
			if (this.status === REJECTED) {
				setTimeout(() => {
					try {
						const returnValue = errorCallback(this.resion)
						resolvePromise(promise2, returnValue, resolve, reject)
					} catch (e) {
						reject(e)
					}
				}, 0)
			}
			if (this.status = PENGDING) {

				this.successCallback.push(() => {
					setTimeout(() => {
						try {
							const returnValue = successCallback(this.value)
							resolvePromise(promise2, returnValue, resolve, reject)
						} catch (e) {
							reject(e)
						}
					}, 0)
				})
				this.errorCallback.push(() => {
					setTimeout(() => {
						try {
							const returnValue = errorCallback(this.resion)
							resolvePromise(promise2, returnValue, resolve, reject)
						} catch (e) {
							reject(e)
						}
					}, 0)
				})
			}
		})

		return promise2
	}
	static all(arr) {
		const result = []
		let index = 0
		return new MyPromise((resolve, reject) => {
			const add = (key, value) => {
				result[key] = value
				index++
				if (index === arr.length) {
					resolve(result)
				}
			}
			arr.forEach((item, index) => {
				if (item instanceof MyPromise) {
					item.then(value => add(index, value), error => reject(error))
				} else {
					add(index, item)
				}
			})
		})
	}
	static resolve(value) {
		if (value instanceof MyPromise) return value
		return new MyPromise((resolve) => {
			resolve(value)
		})
	}
}

// const myPromise = new MyPromise((resolve, reject) => {
// 	setTimeout(() => {
// 		// reject('失败')
// 		resolve('成功')
// 	}, 2000)
// 	// resolve('成功')
// })

// 多次调用then
// myPromise.then(v => {
// 	console.log(v, 777)
// }, e => {
// 	console.log(e, 888)
// })

// myPromise.then(v => {
// 	console.log(v, 11)
// }, e => {
// 	console.log(e, 22)
// })

// myPromise.then(v => {
// 	console.log(v, 33)
// }, e => {
// 	console.log(e, 44)
// })

// 链式调用then方法
// myPromise.then((v) => {
// 		console.log(v, 'v1')
// 		return 2000
// 	}, (e) => {
// 		return 3000
// 	})
// 	.then((v) => {
// 		console.log(v, 'v2')
// 	}, e => console.log(e.message, 6666))

// then不传递参数
// myPromise.then()
// 	.then()
// 	.then(v => console.log(v, 6666), e => console.log(e, 777))

// all方法测试
// const p1 = () => new MyPromise((resolve, reject) => {
// 	setTimeout(() => {
// 		reject('失败')
// 		// resolve('p1')
// 	}, 2000)
// 	// resolve('成功')
// })
// const p2 = () => new MyPromise((resolve, reject) => {
// 	resolve('p2')
// })

// MyPromise.all([2, 4, p1(), p2(), 789]).then(v=>console.log(v,7777),e=>console.log(e,88))

// 测试resolve方法
// MyPromise.resolve(myPromise).then(v=>console.log(v,88))

// 测试finally方法
// const myPromise = new MyPromise((resolve, reject) => {
// 	setTimeout(() => {
// 		// reject('失败')
// 		resolve('成功11')
// 	}, 2000)
// 	// resolve('成功')
// })

// const p1 = () => new MyPromise((resolve, reject) => {
// 	resolve('成功222')
// })
// myPromise.finally(() => {
// 	console.log('finally')
// 	return p1()
// }).then(v => console.log(v, 777))

// 测试catch方法
const myPromise = new MyPromise((resolve, reject) => {
	// setTimeout(() => {
	// 	reject('失败')
	// 	// resolve('成功11')
	// }, 2000)
	// resolve('成功')
	reject('失败')
})

myPromise.then(v => console.log(v, 777)).catch(e=>console.log(e,65))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值