手写promise

function Promise(fn) {
	var self = this;
	self.status = 'pending';
	self.onResolvedCallback = [];
	self.onRejectedCallback = [];

	function resolve(value) {
		if (value instanceof Promise) {
			return value.then(resolve, reject);
		}
		setTimeout(function () {
			if (self.status === 'pending') {
				self.status = 'resolved';
				self.data = value;
				self.onResolvedCallback.forEach(fn => fn(value));
			}
		})
	}

	function reject(reason) {
		setTimeout(function () {
			if (self.status === 'pending') {
				self.status = 'rejected';
				self.data = reason;
				self.onRejectedCallback.forEach(fn => fn(reason));
			}
		})
	}

	try {
		fn(resolve, reject);
	} catch (reason) {
		reject(reason);
	}
}

function resolvePromise(promise2, x, resolve, reject) {
	var then;
	var thenCalledOrThrow = false;
	if (promise2 === x) {
		return reject(new TypeError('Chaining cycle detected for primise!'));
	}
	if (x instanceof Promise) {
		if (x.status === 'pending') {
			x.then(function (v) {
				resolvePromise(promise2, v, resolve, reject);
			}, reject)
		} else {
			x.then(resolve, reject);
		}
		return;
	}
	if ((x !== null) && (typeof x === 'object') || (typeof x === 'function')) {
		try {
			then = x.then;
			if (typeof then === 'function') {
				then.call(x, function rs(y) {
					if (thenCalledOrThrow) return;
					thenCalledOrThrow = true;
					return resolvePromise(promise2,)
				}, function rj(r) {
					if (thenCalledOrThrow) return;
					thenCalledOrThrow = true;
					return reject(r);
				})
			} else {
				resolve(x)
			}
		} catch (error) {
			if (thenCalledOrThrow) return;
			thenCalledOrThrow = true;
			return reject(error);
		}
	}
}

// 版本一
Promise.prototype.then = function (onResolved, onRejected) {
	var self = this;
	var promise2;
	onResolved = typeof onResolved === 'function' ? onResolved : function (v) { return v };
	onRejected = typeof onRejected === 'function' ? onRejected : function (r) { return r };
	if (self.status === 'resolved') {
		return promise2 = new Promise(function (resolve, reject) {
			setTimeout(function () {
				try {
					var x = onResolved(self.data);
					resolvePromise(promise2, x, resolve, reject);
				} catch (reason) {
					reject(reason)
				}
			})
		})
	}
	if (self.status === 'rejected') {
		return promise2 = new Promise(function (resolve, reject) {
			setTimeout(function () {
				try {
					var x = onRejected(self.data);
					resolvePromise(promise2, x, resolve, reject);
				} catch (reason) {
					reject(reason)
				}
			})
		})
	}
	if (self.status === 'pending') {
		return promise2 = new Promise(function (resolve, reject) {
			self.onResolvedCallback.push(function (value) {
				try {
					var x = onResolved(value);
					resolvePromise(promise2, x, resolve, reject);
				} catch (r) {
					reject(r);
				}
			})
			self.onRejectedCallback.push(function (reason) {
				try {
					var x = onRejected(reason);
					resolvePromise(promise2, x, resolve, reject);
				} catch (r) {
					reject(r);
				}
			})
		})
	}
}

// 版本二
Promise.prototype.then = function (onResolved, onRejected) {
	var self = this;
	onResolved = typeof onResolved === 'function' ? onResolved : function (v) { return v };
	onRejected = typeof onRejected === 'function' ? onRejected : function (r) { return r };
	if (self.status === 'resolved') {
		return new Promise(function (resolve, reject) {
			if (self.data instanceof Promise) {
				self.data.then(onResolved, onRejected)
			} else {
				try {
					resolve(onResolved(self.data));
				} catch (e) {
					reject(e)
				}
			}
		})
	}
	if (self.status === 'rejected') {
		return new Promise(function (resolve, reject) {
			try {
				resolve(onRejected(self.data));
			} catch (e) {
				reject(e)
			}
		})
	}
	if (self.status === 'pending') {
		return new Promise(function (resolve, reject) {
			self.onResolvedCallback.push(function () {
				if (self.data instanceof Promise) {
					self.data.then(onResolved, onRejected)
				} else {
					try {
						resolve(onResolved(self.data))
					} catch (e) {
						reject(e);
					}
				}
			})
			self.onRejectedCallback.push(function () {
				try {
					resolve(onRejected(self.data))
				} catch (e) {
					reject(e);
				}
			})
		})
	}
}

Promise.prototype.catch = function (onRejected) {
	return this.then(null, onRejected);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值