JavaScript:自定义实现Promise

自定义Promise

简单版

  • Promise.js
// 声明构造函数
function Promise(executor){
	// 给对象添加属性
	this.PromiseState = 'pending';
	this.PromiseResult = null; // 存放promise对象的结果
	// 用于处理异步任务回调的执行,使用数组是为了能够进行指定多个回调
	this.callbacks = [], 
	
	// 保存实例对象中的this值
	const self = this;
	
	// 定义resolve函数
	function resolve(data){
		// 判断状态,让promise对象状态只能改变一次
		if(self.PromiseState !== 'pending') return ;
		
		// 修改对象的状态(promiseState)
		this.PromiseState = 'fullfilled'; // 或者resolved
		
		// 设置对象结果值(promiseResult)
		this.PromiseResult = data;

		// 调用成功的回调函数,使用forEach是为了让链式调用的结果不会被覆盖
		setTimeout(() => {
			self.callbacks.forEach(item => {
				item.onResolved(data);
			})
		})
	}
	
	// 定义reject函数
	function reject(data){
		// 判断状态,让promise对象状态只能改变一次
		if(self.PromiseState !== 'rejected') return ;
		
		// 修改对象的状态(promiseState)
		this.PromiseState = 'rejected'; // 或者resolved
		
		// 设置对象结果值(promiseResult)
		this.PromiseResult = data;
			
		// 调用失败的回调函数
		setTimeout(() => {
			self.callbacks.forEach(item => {
				item.onRejected(data);
			})
		})
	}
	
	// throw抛出异常处理
	// 同步调用【执行器函数】
	try{
		executor(resolve,reject);
	}catch(e){
		// 修改promise对象状态为失败
	    reject(e);
	}
}

// 自定义then()方法
Promise.prototype.then = function((onResolved,onRejected) => {

	const self = this;
	
	// 判断回调函数参数(实现异常穿透的原理)
	if(typeof onRejected !== 'function'){
		onRejected = reason => {
			throw reason	
		}	
	}

	if(typeof onResolved !== 'function'){
		onResolved = value => value;
	}
	
	return new Promise((resolve,reject)=>{
		// 封装函数
		function callback(type){
			try{
				// 获取回调函数的执行结果
				let result = type(self.PromiseResult);
				// 判断
				if(result instanceof Promise){
					// 如果是promise类型的对象
					result.then(v => {
						resolve(v);	
					},r => {
						reject(r);
					})
				}else {
					resolve(result)	
				}
			}catch(e){
				reject(e);
			}
		}
		
		if(this.PromiseState === 'fullfilled'){
			setTimeout(() => {
				callback(onResolved)
			})
		}
		
		if(this.PromiseState === 'rejected'){
			setTimeout(() => {
				callback(onRejected)
			})
		}
		
		// 判断pending状态
		if(this.PromiseState === 'pending'){
			// 保存回调函数
			this.callbacks.push({
				onResolved:function(){
					callback(onResolved)
				},
				onRejected:function(){
					callback(onRejected)
				},
			})
		}
	})
})

Promise.prototype.catch = function(onRejected){
	return this.then(undefined,onRejected);
}

// 封装静态resolve方法
Promise.resolve = function(value){
	// 返回promise对象
	return new Promise((resolve,reject) => {
		if(value instanceof Promise){
			value.then(v => {
				resolve(v);
			},r => {
				reject(r);
			})
		}else {
			resolve(value);	
		}
	}
}

// 封装静态reject()方法
Promise.reject = function (error){
	return new Promise((resolve,reject) => {
		reject(error);
	})
}

// 封装静态all()方法
Promise.all = function(promises){
	// 返回结果为promise对象
	return new Promise((resolve,reject) => {
		// 计数变量
		let count = 0;
		// 存放成功结果的数组
		let arr = [];
		for(let i = 0; i<promises.length; i++){
			promises[i].then(v => {
				// 每个promise都成功时执行成功回调
				count++// 往数组中存放结果
				arr[i] = v;
				// 如果count结果与promises数组的长度相同
				if(count === promises.length){
					// 将arr数组作为结果
					resolve(arr);	
				}
			},r=>{
				reject(r)
			})
		}
	});
}

// 封装race方法
Promise.race = function(promise){
	return new Promise((resolve,reject) => {
		for(let i = 0; i<promises.length; i++){
			promises[i].then(v => {
				resolve(v);
			},r => {
				reject(r);
			})
		}
	})
}
  • index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
	<script src="./promise.js"></script>
<body>
    <script>
      let p = new Promise((resolve,reject) => {
      	resolve('ok');
      });
      p.then(value => {
      	console.log(value)
      },error => {
      	console.log(error)
      })
    </script>
</body>
</html>

将promise.js封装成类class

class Promise{
	constructor(executor){
		// 给对象添加属性
		this.PromiseState = 'pending';
		this.PromiseResult = null; // 存放promise对象的结果
		// 用于处理异步任务回调的执行,使用数组是为了能够进行指定多个回调
		this.callbacks = [], 
		
		// 保存实例对象中的this值
		const self = this;
		
		// 定义resolve函数
		function resolve(data){
			// 判断状态,让promise对象状态只能改变一次
			if(self.PromiseState !== 'pending') return ;
			
			// 修改对象的状态(promiseState)
			this.PromiseState = 'fullfilled'; // 或者resolved
			
			// 设置对象结果值(promiseResult)
			this.PromiseResult = data;
	
			// 调用成功的回调函数,使用forEach是为了让链式调用的结果不会被覆盖
			setTimeout(() => {
				self.callbacks.forEach(item => {
					item.onResolved(data);
				})
			})
		}
		
		// 定义reject函数
		function reject(data){
			// 判断状态,让promise对象状态只能改变一次
			if(self.PromiseState !== 'rejected') return ;
			
			// 修改对象的状态(promiseState)
			this.PromiseState = 'rejected'; // 或者resolved
			
			// 设置对象结果值(promiseResult)
			this.PromiseResult = data;
				
			// 调用失败的回调函数
			setTimeout(() => {
				self.callbacks.forEach(item => {
					item.onRejected(data);
				})
			})
		}
		
		// throw抛出异常处理
		// 同步调用【执行器函数】
		try{
			executor(resolve,reject);
		}catch(e){
			// 修改promise对象状态为失败
		    reject(e);
		}
	}
	
	then(onResolved,onRejected){
		const self = this;
	
		// 判断回调函数参数(实现异常穿透的原理)
		if(typeof onRejected !== 'function'){
			onRejected = reason => {
				throw reason	
			}	
		}
	
		if(typeof onResolved !== 'function'){
			onResolved = value => value;
		}
		
		return new Promise((resolve,reject)=>{
			// 封装函数
			function callback(type){
				try{
					// 获取回调函数的执行结果
					let result = type(self.PromiseResult);
					// 判断
					if(result instanceof Promise){
						// 如果是promise类型的对象
						result.then(v => {
							resolve(v);	
						},r => {
							reject(r);
						})
					}else {
						resolve(result)	
					}
				}catch(e){
					reject(e);
				}
			}
			
			if(this.PromiseState === 'fullfilled'){
				setTimeout(() => {
					callback(onResolved)
				})
			}
			
			if(this.PromiseState === 'rejected'){
				setTimeout(() => {
					callback(onRejected)
				})
			}
			
			// 判断pending状态
			if(this.PromiseState === 'pending'){
				// 保存回调函数
				this.callbacks.push({
					onResolved:function(){
						callback(onResolved)
					},
					onRejected:function(){
						callback(onRejected)
					},
				})
			}
		})
	}
	
	catch(onRejected){
		return this.then(undefined,onRejected);
	}
	
	// 封装静态resolve方法
	static resolve(value){
		// 返回promise对象
		return new Promise((resolve,reject) => {
			if(value instanceof Promise){
				value.then(v => {
					resolve(v);
				},r => {
					reject(r);
				})
			}else {
				resolve(value);	
			}
		}
	}

	// 封装静态reject()方法
	static reject(error){
		return new Promise((resolve,reject) => {
			reject(error);
		})
	}

	// 封装静态all()方法
	static all(promises){
		// 返回结果为promise对象
		return new Promise((resolve,reject) => {
			// 计数变量
			let count = 0;
			// 存放成功结果的数组
			let arr = [];
			for(let i = 0; i<promises.length; i++){
				promises[i].then(v => {
					// 每个promise都成功时执行成功回调
					count++// 往数组中存放结果
					arr[i] = v;
					// 如果count结果与promises数组的长度相同
					if(count === promises.length){
						// 将arr数组作为结果
						resolve(arr);	
					}
				},r=>{
					reject(r)
				})
			}
		});
	}

	// 封装race方法
	static race (promise){
		return new Promise((resolve,reject) => {
			for(let i = 0; i<promises.length; i++){
				promises[i].then(v => {
					resolve(v);
				},r => {
					reject(r);
				})
			}
		})
	}
}

复杂版

class MyPromise {
    constructor(executor) {
        this.status = 'pending'; // promise状态信息,默认为pending
        this.value = undefined; // 成功时的返回值
        this.reason = undefined; // 失败时的返回值
        this.onResolvedCallbacks = []; // 存储成功的回调
        this.onRejectedCallbacks = []; // 存储失败的回调
        try {
            /**
             * @description: 执行器函数;通过bind调用函数后返回的是一个函数对象;this指向promise实例对象
             */
            executor(this.resolve.bind(this), this.reject.bind(this));
        } catch (error) {
            this.reject(error);
        }
    }

    // 普通的resolve成功回调函数
    resolve(value) {
        if (this.status === 'pending') {
            this.status = 'fulfilled';
            this.value = value;
            // 调用所有已注册的成功回调函数
            while (this.onResolvedCallbacks.length) {
                const callback = this.onResolvedCallbacks.shift();
                // 执行成功回调
                callback(this.value);
            }
        }
    }

    // 普通的reject失败回调函数
    reject(reason) {
        if (this.status === 'pending') {
            this.status = 'rejected';
            this.reason = reason;
            // 调用所有已注册的的失败回调函数
            while (this.onRejectedCallbacks.length) {
                const callback = this.onRejectedCallbacks.shift();
                // 执行失败回调
                callback(this.reason);
            }
        }
    }

    // 原型then方法,注册成功回调和失败回调
    then(onResolved, onRejected) {
        // 判断传进来的是函数对象类型还是基本类型
        onResolved = typeof onResolved === 'function' ? onResolved : value => value;
        onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };

        // 定义一个新的promise
        const promise2 = new MyPromise((resolve, reject) => {
            // 如果promise状态为已完成,则执行成功回调
            if (this.status === 'fulfilled') {
                setTimeout(() => {
                    try {
                        const x = onResolved(this.value);
                        this._resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });
            // 如果promise状态为失败
            } else if (this.status === 'rejected') {
                setTimeout(() => {
                    try {
                        const x = onRejected(this.reason);
                        this._resolvePromise(promise2, x, resolve, reject);
                    } catch (error) {
                        reject(error);
                    }
                });
            }
            // 处理处于pending状态的回调
            else {
                // 添加进回调数组中等待处理
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onResolved(this.value);
                            // 
                            this._resolvePromise(promise2, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    });
                });

                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            const x = onRejected(this.reason);
                            this._resolvePromise(promise2, x, resolve, reject);
                        } catch (error) {
                            reject(error);
                        }
                    });
                });
            }
        });

        // 将新的Promise对象返回,从而可以继续后续的处理或者链式调用
        return promise2;
    }

    /**
     * @description: 用来对Promise中的值进行处理的,它将决议(resolve)与拒绝(reject)过程抽象成一个可重用的函数。
     * 它会在then方法中被多次调用以检查promise参数是否Fulfilled或Rejected,并返回promise的最终结果。
     * @param promise2 一个新的Promise实例
     * @param x 当前的Promise实例
     * @param resolve 新Promise实例的resolve方法
     * @param reject 新Promise实例的reject方法
     */    
    _resolvePromise(promise2, x, resolve, reject) {
        // 处理promise链式调用中可能出现的循环依赖问题
        if (promise2 === x) {
            reject(new TypeError('Chaining cycle detected'));
        }

        // 如果x是Promise对象,进行链式调用
        if (x instanceof MyPromise) {
            x.then(
                value => this._resolvePromise(promise2, value, resolve, reject),
                reason => reject(reason)
            );
        } 
        // 判断x是否为object或者function类型(这些类型里面可能有自己的then方法)
        else if (x !== null && (typeof x === 'object' || typeof x === 'function')) {
            let called = false;
            try {
                const then = x.then;
                // 如果有then方法
                if (typeof then === 'function') {
                    then.call(x,
                        value => {
                            if (called) return;
                            called = true;
                            this._resolvePromise(promise2, value, resolve, reject);
                        },
                        reason => {
                            if (called) return;
                            called = true;
                            reject(reason);
                        }
                    );
                // 没有则直接resolve掉
                } else {
                    resolve(x);
                }
            } catch (error) {
                if (called) return;
                called = true;
                reject(error);
            }
        } 
        // 如果都不是object或者function类型,则之际resolve处理掉
        else {
            resolve(x);
        }
    }

    // 原型catch方法
    catch(onRejected) {
        return this.then(null, onRejected);
    }

    // 原型finally方法
    finally(onFinally) {
        return this.then(
            value => MyPromise.resolve(onFinally()).then(() => value),
            reason => MyPromise.resolve(onFinally()).then(() => { throw reason })
        );
    }

    // 静态resolve方法,将普通类型转为promise类型,并且状态为fulfilled
    static resolve(value) {
        if (value instanceof MyPromise) {
            return value;
        }
        return new MyPromise(resolve => resolve(value));
    }

    // 静态reject方法,将普通类型转为promise类型,并且状态为reject
    static reject(reason) {
        return new MyPromise((resolve, reject) => reject(reason));
    }

    // 静态all方法,并行执行promise
    static all(promises) {
        return new MyPromise((resolve, reject) => {
            const results = [];
            let count = 0;
            function collectResult(index, value) {
                results[index] = value;
                count++;
                if (count === promises.length) {
                    resolve(results);
                }
            }
            promises.forEach((promise, index) => {
                promise.then(
                    value => collectResult(index, value),
                    reason => reject(reason)
                );
            });
        });
    }

    // 静态race方法,返回最先处理完的promise对象的结果
    static race(promises) {
        return new MyPromise((resolve, reject) => {
            promises.forEach(promise => {
                promise.then(resolve, reject);
            });
        });
    }

    // 静态any方法,返回最先变为fulfilled状态的promise对象的结果
    static any(promises) {
        return new MyPromise((resolve, reject) => {
            let count = promises.length;
            const reasons = [];
            promises.forEach((promise, index) => {
                promise.then(
                    value => resolve(value),
                    reason => {
                        reasons[index] = reason; // 将失败的原因存储下来
                        count--;
                        if (count === 0) {
                            reject(reasons); // 当所有Promise都失败时,将所有失败原因组成数组,传递给promise的reject函数
                        }
                    }
                );
            });
        });
    }
}


let promise = new MyPromise((resolve, reject) => {
    if (3 > 4) {
        resolve("yes")
    } else {
        reject("no")
    }
})

promise.then((resolve) => { console.log(resolve); }, (reject) => { console.log(reject); })
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值