手写Promise

业务背景:为了对promise有更深刻的理解和认识,手动实现一个promise

按照以下步骤依次实现Promise的手动封装:
1.promise就是一个类,再执行这个类的时候,需要传递一个执行器进去 执行器会立即执行
2.Promise有三种状态,分别为 成功fulfilled 失败 rejected 等待pending
pending–fulfilled
pending–rejected
状态一旦确定不能修改
3.relove和reject函数是用来更改状态的
resolve: fulfilled
reject: rejected
4.then方法内部就是判断状态 如果状态是成功 调用成功回调函数 如果是失败调用失败回调函数 then方法是被定义在原型对象上的
5.then成功回调有个参数 表示成功之后的值 失败回调有个参数 表示失败后的值
6. 同一个promise对象下面的then方法是可以被调用多次的(需要用到while循环)
7. then方法是可以被链式调用的, 后面then方法的回调函数拿到值的是上一个then方法的回调函数的返回值(返回值可能是基本类型 也可能是promise)
判断 x 的值是普通值还是promise对象
如果是普通值 直接调用resolve
如果是promise对象 查看promsie对象返回的结果
再根据promise对象返回的结果 决定调用resolve 还是调用reject
8.then方法链式调用识别promise对象自返回(判断返回的和当前是否一样 出现promise的循环调用 提示错误)
9.捕获错误(执行器的错误,then回调函数的错误)
10.then参数变成可选参数
11.promise.all(解决并发 允许我们按照异步代码调用的顺序得到异步代码执行的结果)
12.promise.resolve()方法是将给定的值转换成promise对象 返回值就是promise对象 会包裹给定的值 如果值是promise对象 直接返回 否则创建promise对象再返回
13.finally方法 无论什么结果都会执行;可以链式调用then;属于实例方法
14.catch方法 调用then方法 第一个参数传undefined 第二个是失败回调

const PENDING = 'pending'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class myPromise {
	constructor(executor){
		// 捕获执行器错误
		try {
			executor(this.resolve, this.reject)
		} catch (error) {
			this.reject(error)		
		}
	}
	status= PENDING //状态
	value = undefined // 成功的参数
	reason = undefined // 失败的原因
	successCallback = [] //成功的回调
	failCallback = [] //成功的回调

	resolve = value =>{ // 之所以用箭头函数 就是让调用resolve的this指向这个实例对象myPromise
		// 判断状态是否是pengding 不是终止更改
		if (this.status !== PENDING) return
		// 状态更改为成功
		this.status = FULFILLED
		// 保存成功后的值
		this.value = value
		// 判断成功回调是否存在 存在 调用
		// this.successCallback && this.successCallback(this.value)
		// 处理then方法多次调用执行
		while(this.successCallback.length) this.successCallback.shift()()
	}
	
	reject = reason => {
		if (this.status !== PENDING) return
		// 状态更改为失败
		this.status = REJECTED
		// 保存失败的原因
		this.reason = reason
		// 判断失败回调是否存在 存在 调用
		// this.failCallback && this.failCallback(this.value)
		while(this.failCallback.length) this.failCallback.shift()()
	}

	then (successCallback, failCallback) {
		// then方法变成可选参数
		successCallback = successCallback ? successCallback : value => value
		failCallback = failCallback ? failCallback : reason => { throw reason}
		// then方法的链式调用 每个then都返回promise
		let promise1 = new myPromise ((resolve, reject)=>{
			if (this.status == FULFILLED) {  // 成功状态调用成功的回调函数
				setTimeout(()=>{
					try {  // 捕获then方法错误
						let x = successCallback(this.value) //保存前一个then返回的结果
						// 判断 x 的值是普通值还是promise对象
						// 如果是普通值 直接调用resolve 
						// 如果是promise对象 查看promsie对象返回的结果 
						// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
						orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
					} catch (error) {
						reject(error)	
					}
				},0)
			} else if (this.status == REJECTED) { // 失败状态调用的回失败调函数
				setTimeout(()=>{
					try {
						let x = failCallback(this.reason) //保存前一个then返回的结果
						// 判断 x 的值是普通值还是promise对象
						// 如果是普通值 直接调用resolve 
						// 如果是promise对象 查看promsie对象返回的结果 
						// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
						orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
					} catch (error) {
						reject(error)	
					}
				},0)
			} else { //等待 是异步逻辑
				// 需要把成功和失败的回调存起来
				this.successCallback.push(()=>{
					setTimeout(()=>{
						try {
							let x = successCallback(this.value) //保存前一个then返回的结果
							// 判断 x 的值是普通值还是promise对象
							// 如果是普通值 直接调用resolve 
							// 如果是promise对象 查看promsie对象返回的结果 
							// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
							orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
						} catch (error) {
							reject(error)	
						}
					},0)
				})
				this.failCallback.push(()=>{
					setTimeout(()=>{
						try {
							let x = failCallback(this.reason) //保存前一个then返回的结果
							// 判断 x 的值是普通值还是promise对象
							// 如果是普通值 直接调用resolve 
							// 如果是promise对象 查看promsie对象返回的结果 
							// 再根据promise对象返回的结果 决定调用resolve 还是调用reject
							orPromiseFn(promise1, x, resolve, reject) // 传递给下一个then
						} catch (error) {
							reject(error)	
						}
					},0)
				})
			}
		})
		return promise1
	}
	
	finally (callback) {
		return this.then(val => {
			return myPromise.resolve(callback()).then(()=>val)
		},reason=>{
			return myPromise.resolve(callback()).then(()=>{throw reason})
		})
	}

	catch (failCallback) {
		return this.then(undefined, failCallback)
	}

	static all(array){ //静态方法
		let result = []
		let index = 0
		return new myPromise((resolve, reject)=>{
			function addData(key, val) {
				result[key] = val
				index ++
				if(index == array.length){
					resolve(result)
				}
			}
			for(let i=0; i<array.length; i++){
				let current = array[i]
				if(current instanceof myPromise){
					// promise对象
					current.then(val => addData(i, val), reason=>addData(i, reason))
				} else {
					// 普通值
					addData(i, current)
				}
			}
		})
	}

	static resolve (cur) {
		if(cur instanceof myPromise) return cur
		return new myPromise(resolve => resolve(cur))
	}

}
function orPromiseFn (promise1, x, resolve, reject) {
	if(promise1 === x) {
		return reject(new TypeError('Chaining cycle detected for promise #<Promise>'))
	}
	if(x instanceof myPromise) {
		//promise对象 成功走成功 失败走失败
		x.then(value=> resolve(value),reason=> reject(reason)) 
	} else {
		// 普通值 直接调用resolve
		resolve(x)
	}
}
module.exports = myPromise

说明:只是初步实现了功能,没有过多兼容,欢迎大佬讨论交流

觉得不错,赏个关注呗😀,不胜感激Thanks♪(・ω・)ノ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值