skip to content
天真笔录

手写Promise

/ 2 min read

const PROMISE_PENDING = "pending";
const PROMISE_FULFILLED = "fulfilled";
const PROMISE_REJECTED = "rejected";

class MyPromise {
	constructor(executor) {
		this.initValue();
		this.initBind();

		try {
			executor(this.resolve, this.reject);
		} catch (error) {
			this.reject(error);
		}
	}

	initValue() {
		this.promiseResult = undefined;
		this.status = "pending";
		this.fulfilledCallbacks = [];
		this.rejectedCallbacks = [];
	}

	initBind() {
		this.resolve = this.resolve.bind(this);
		this.reject = this.reject.bind(this);
	}

	resolve(value) {
		if (this.status === PROMISE_PENDING) {
			queueMicrotask(() => {
				if (this.status !== PROMISE_PENDING) return;
				this.promiseResult = value;
				this.status = PROMISE_FULFILLED;

				while (this.fulfilledCallbacks.length) {
					this.fulfilledCallbacks.shift()(this.promiseResult);
				}
			});
		}
	}

	reject(reason) {
		if (this.status === PROMISE_PENDING) {
			queueMicrotask(() => {
				if (this.status !== PROMISE_PENDING) return;
				this.promiseResult = reason;
				this.status = PROMISE_REJECTED;

				while (this.rejectedCallbacks.length) {
					this.rejectedCallbacks.shift()(this.promiseResult);
				}
			});
		}
	}

	then(onFulfilled, onRejected) {
		// onFulfilled,onRejected确保是函数,因为catch时只有一个参数onRejected,要保证参数传递
		onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (value) => value;
		onRejected =
			typeof onRejected === "function"
				? onRejected
				: (reason) => {
						throw reason;
				  };

		const thenPromise = new MyPromise((resolve, reject) => {
			const resolvePromise = (cb) => {
				try {
					const x = cb(this.promiseResult);
					if (x instanceof MyPromise) {
						x.then(resolve, reject);
					} else {
						resolve(x);
					}
				} catch (error) {
					reject(error);
				}
			};

			if (this.status === PROMISE_FULFILLED) {
				resolvePromise(onFulfilled);
			}
			if (this.status === PROMISE_REJECTED) {
				resolvePromise(onRejected);
			}
			if (this.status === PROMISE_PENDING) {
				this.fulfilledCallbacks.push(resolvePromise.bind(this, onFulfilled));
				this.rejectedCallbacks.push(resolvePromise.bind(this, onRejected));
			}
		});

		return thenPromise;
	}

	catch(onRejected) {
		return this.then(undefined, onRejected);
	}

	finally(onFinally) {
		this.then(
			() => {
				onFinally();
			},
			() => {
				onFinally();
			},
		);
	}

	static all(promiseList) {
		const result = [];
		let count = 0;

		return new MyPromise((resolve, reject) => {
			const addData = (promise, index) => {
				result[index] = promise;
				count++;
				if (count === promiseList.length) {
					resolve(result);
				}
			};

			promiseList.forEach((promise, index) => {
				if (promise instanceof MyPromise) {
					promise.then(
						(res) => {
							addData(promise, index);
						},
						(err) => {
							reject(err);
						},
					);
				} else {
					addData(promise, index);
				}
			});
		});
	}
}
  1. 完成链式调用
  2. 添加实例catch和finally
  3. 添加静态方法all,其他如race,any都是类似
  • 测试
const p = new MyPromise((resolve, reject) => {
	resolve("success");
	// reject('fail')
	// setTimeout(() => {
	//   resolve('timeout success')
	// }, 1000);
});

p.then((res) => {
	console.log("res==========================", res);
})
	.catch((err) => {
		console.log("catch err==========================", err);
	})
	.finally(() => {
		console.log("finally");
	});