promise 一直是常用的,现在自己一步一步实现一下,加深理解。
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
function PromiseZ(fn) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined
this.onFulfilledCallback = []; // 需要在then方法里赋值
this.onRejectedCallback = []; // 需要在then方法里赋值
const me = this;
function resolve(value) {
if (me.status === PENDING) {
me.status = FULFILLED;
me.value = value;
queueMicrotask(() => {
me.onFulfilledCallback.forEach((fun) => {
fun(value)
})
})
}
}
function reject(reason) {
if (me.status === PENDING) {
me.status = REJECTED;
me.reason = reason;
queueMicrotask(() => {
me.onRejectedCallback.forEach((fun) => {
fun(reason)
})
})
}
}
try {
fn(resolve, reject);
} catch (e) {
reject(e);
}
}
function resolvePromise(promise, res, resolve, reject) {
if (promise === res) {//防止循环引用
return reject(new TypeError('循环引用'))
}
let called;//防止重复执行
if (res !== null && (typeof res === 'function' || typeof res === 'object')) {
try {//防止promise执行报错
let then = res.then;//判断是否promise就判断是否存在then方法
if (typeof then === 'function') {//如果返回的是promise,只需要在返回的promise的then方法中下一步需要执行的函数
then.call(res, (res2) => {
if (called) return;
called = true;
resolvePromise(promise, res2, resolve, reject);//如果是promise继续递归执行,直到不是promise,依次执行外层的resolve,让promise状态改变
})
} else {//如果不是promise,有可能是undefine、onfulfilled或onrejected的返回的普通值,就直接将这个值返回,将外层的promise状态改变
if (called) return;
called = true;
resolve(then)
}
} catch (e) {
if (called) return;
called = true;
reject(e)
}
} else {
resolve(res)
}
}
PromiseZ.prototype.then = function (onFulfilled, onRejected) {
const me = this;
const onFulfilledCallback = typeof onFulfilled === 'function' ? onFulfilled : value => value;
const onRejectedCallback = typeof onRejected === 'function' ? onRejected : reason => { throw reason };
let x = null
let promise2 = new PromiseZ((resolve, reject) => {
if (me.status === FULFILLED) {
queueMicrotask(() => {
x = onFulfilledCallback(me.value);
resolvePromise(promise2, x, resolve, reject)
})
} else if (me.status === REJECTED) {
queueMicrotask(() => {
x = onRejectedCallback(me.reason);
resolvePromise(promise2, x, resolve, reject)
})
} else {
me.onFulfilledCallback.push((value) => {
try {
x = onFulfilledCallback(value);
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
});
me.onRejectedCallback.push((reason) => {
try {
x = onRejectedCallback(reason);
resolvePromise(promise2, x, resolve, reject)
} catch (e) {
reject(e);
}
});
}
})
return promise2
}
let p = new PromiseZ((res) => {
res(11);
});
p.then((value) => {
return new PromiseZ((res) => {
res(value)
})
}).then((value) => {
console.log(value)
})