手写JS Promise函数

手写JS Promise函数

const STATE = {
	PENDING: "pending",
	FULFILLED: "fulfilled",
	REJECTED: "rejected",
};

function isPromise(obj) {
	return !!(
		obj &&
		typeof obj === "object" &&
		obj.then &&
		typeof obj.then === "function"
	);
}

function runMicroHandler(callback) {
	// 判断是node环境
	if (process && process.nextTick) {
		process.nextTick(callback);
	}
	// 判断是浏览器环境
	else if (MutationObserver) {
		const p = document.createElement("p");
		const observer = new MutationObserver(callback);
		observer.observe(p, { childList: true });
		p.innerHtml = "1";
	} else {
		setTimeout(callback, 0);
	}
}
class MyPromise {
	constructor(executor) {
		this._value = null;
		this._state = STATE.PENDING;
		this._handlers = [];
		try {
			executor(this._resolve.bind(this), this._reject.bind(this));
		} catch (error) {
			this._changeState(error, STATE.REJECTED);
		}
	}

	_pushHandler(handler, state, resolve, reject) {
		this._handlers.push({ executor: handler, state, resolve, reject });
	}

	// then把函数放入队列
	then(onFulfilled, onRejected) {
		return new MyPromise((resolve, reject) => {
			this._pushHandler(onFulfilled, STATE.FULFILLED, resolve, reject);
			this._pushHandler(onRejected, STATE.REJECTED, resolve, reject);
			this._runHandlers();
		});
	}

	_runOneHandler(handler) {
		runMicroHandler(() => {
			if (this._state !== handler.state) return;
			if (typeof handler.executor !== "function") {
				handler.resolve(this._value);
				return;
			}
			try {
				const res = handler.executor(this._value);
				// 如果then还是返回一个promise,那then的状态要看返回的promise状态
				if (isPromise(res)) {
					res.then(handler.resolve, handler.reject);
				}
				handler.resolve(res);
			} catch (error) {
				handler.reject(error);
			}
		});
	}

	// 在合适的时候运行队列中的函数
	_runHandlers() {
		if (this._state === STATE.PENDING) return;
		while (this._handlers[0]) {
			this._runOneHandler(this._handlers[0]);
			this._handlers.shift();
		}
	}

	_changeState(value, state) {
		// 状态修改之后就不能再次修改
		if (this._state !== STATE.PENDING) return;
		this._value = value;
		this._state = state;
		this._runHandlers();
	}

	_resolve(value) {
		this._changeState(value, STATE.FULFILLED);
	}

	_reject(err) {
		this._changeState(err, STATE.REJECTED);
	}
}

const p = new MyPromise((resolve, reject) => {
	resolve(123);
	reject(456);
});

const p1 = new MyPromise((resolve) => {
	resolve(123);
});

const p2 = p1.then(
	(res) => {
		return res;
	},
	(err) => {},
);

const p3 = p2.then((res) => {
	return new MyPromise((resolve) => {
		resolve(res);
	});
});

// @ts-ignore
const p4 = p3.then(123);

console.log("p", p);
console.log("p1", p1);
setTimeout(() => {
	console.log("p2", p2);
}, 10);
setTimeout(() => {
	console.log("p3", p3);
}, 20);
setTimeout(() => {
	console.log("p4", p4);
}, 30);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值