大前端:练习题-手写Promise

const { reject } = require('lodash');

// 用常量定义三种状态,是因为有代码提示
const PENDDING = 'pendding'; // 等待
const FULFILLED = 'fulfilled'; // 成功
const REJECTED = 'rejected'; // 失败

class MyPromise {
	constructor(execute) {
		try {
			execute(this.resolve, this.reject);
		} catch (e) {
			this.reject(e);
		}
	}

	// promise 状态
	status = PENDDING;
	// 成功之后的值
	value = undefined;
	// 失败之后的原因
	reason = undefined;
	// 成功回调状态
	successCallBack = [];
	// 失败回调状态
	failCallBack = [];

	// 定义为箭头函数,this指向对象实例
	resolve = (value) => {
		// 如果状态不是等待,阻止程序继续执行
		if (this.status != PENDDING) return;
		// 状状态改变为成功
		this.status = FULFILLED;
		// 保存成功之后的值
		this.value = value;
		while (this.successCallBack.length) this.successCallBack.shift()();
	};
	reject = (reason) => {
		// 如果状态不是等待,阻止程序继续执行
		if (this.status != PENDDING) return;
		// 状状态改变为失败
		this.status = REJECTED;
		// 失败之后的原因
		this.reason = reason;
		while (this.failCallBack.length) this.failCallBack.shift()();
	};
	then(successCallBack, failCallBack) {
		successCallBack = successCallBack ? successCallBack : (value) => value;
		failCallBack = failCallBack
			? failCallBack
			: (reason) => {
					throw reason;
			  };
		let promise2 = new MyPromise((resolve, rejected) => {
			if (this.status === FULFILLED) {
				setTimeout(() => {
					try {
						let x = successCallBack(this.value);
						// 判断X是普通值 ,还是Promise对象
						// 如果是普通值,直接调用Promise对象
						// 如果是Promise对象,查看对象返回结果
						// 再根据Promise对象的返回结果,决定调用resolve,还是调用rejected
						resolvePromise(promise2, x, resolve, rejected);
					} catch (e) {
						rejected(e);
					}
				}, 0);
			} else if (this.status === REJECTED) {
				setTimeout(() => {
					try {
						let x = failCallBack(this.reason);
						// 判断X是普通值 ,还是Promise对象
						// 如果是普通值,直接调用Promise对象
						// 如果是Promise对象,查看对象返回结果
						// 再根据Promise对象的返回结果,决定调用resolve,还是调用rejected
						resolvePromise(promise2, x, resolve, rejected);
					} catch (e) {
						rejected(e);
					}
				}, 0);
			} else {
				// 等待
				// 把成功、失败的状态存起来,方便调用
				this.successCallBack.push(() => {
					setTimeout(() => {
						try {
							let x = successCallBack(this.value);
							// 判断X是普通值 ,还是Promise对象
							// 如果是普通值,直接调用Promise对象
							// 如果是Promise对象,查看对象返回结果
							// 再根据Promise对象的返回结果,决定调用resolve,还是调用rejected
							resolvePromise(promise2, x, resolve, rejected);
						} catch (e) {
							rejected(e);
						}
					}, 0);
				});
				this.failCallBack.push(() => {
					setTimeout(() => {
						try {
							let x = failCallBack(this.reason);
							// 判断X是普通值 ,还是Promise对象
							// 如果是普通值,直接调用Promise对象
							// 如果是Promise对象,查看对象返回结果
							// 再根据Promise对象的返回结果,决定调用resolve,还是调用rejected
							resolvePromise(promise2, x, resolve, rejected);
						} catch (e) {
							rejected(e);
						}
					}, 0);
				});
				console.log('等待中....');
			}
		});
		return promise2;
	}
	// 无论成功或失败,都执行一次
	finally(callback) {
		return this.then(
			(value) => {
				return MyPromise.resolve(callback()).then(() => value);
			},
			(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++;
				console.log(index);
				if (index === array.length) {
					console.log('fail');
					resolve(result);
				}
			}

			for (let i = 0; i < array.length; i++) {
				let current = array[i];
				if (current instanceof MyPromise) {
					// Promise对象
					current.then(
						(value) => addData(i, value),
						(reason) => reject(reason)
					);
				} else {
					// 普通值,直接返回结果
					addData(i, array[i]);
				}
			}

			resolve(result);
		});
	}
	static resolve(value) {
		if (value instanceof MyPromise) {
			return value;
		} else {
			return new MyPromise((resolve) => resolve(value));
		}
	}
}

function resolvePromise(promise2, x, resolve, rejected) {
	if (promise2 === x) {
		return new TypeError('禁止循环执行');
	}
	if (x instanceof MyPromise) {
		// Promise 对象
		x.then(resolve, rejected);
	} else {
		// 普通值
		resolve(x);
	}
}

module.exports = MyPromise;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值