const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';
class myPromise {
constructor(executor) {
this.status = PENDING;
this.value = undefined;
this.reason = undefined;
this.onFulfillCallbacks = [];
this.onRejectCallbacks = [];
let resolve = (value) => {
this.status = FULFILLED;
this.value = value;
this.onFulfillCallbacks.forEach((fn) => fn());
};
let reject = (reason) => {
this.status = REJECTED;
this.reason = reason;
this.onRejectCallbacks.forEach((fn) => fn());
}
try {
executor(resolve, reject);
} catch (error) {
reject(error);
};
};
then(onFulfill, onReject) {
onFulfill = typeof onFulfill === 'function' ? onFulfill : (value) => value;
onReject = typeof onReject === 'function' ? onReject : (error) => {
throw error;
};
let promise2 = new myPromise((resolve, reject) => {
if (this.status === FULFILLED) {
setTimeout(() => {
try {
let x = onFulfill(this.value);
this.resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
};
if (this.status === REJECTED) {
setTimeout(() => {
try {
let x = onReject(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
} catch (e) {
reject(e);
}
}, 0);
};
if (this.status === PENDING) {
this.onFulfillCallbacks.push(() => {
try {
setTimeout(() => {
let x = onFulfill(this.value);
this.resolvePromise(promise2, x, resolve, reject);
}, 0);
} catch (e) {
reject(e)
}
})
this.onRejectCallbacks.push(() => {
try {
setTimeout(() => {
let x = onReject(this.reason);
this.resolvePromise(promise2, x, resolve, reject);
}, 0)
} catch (e) {
reject(e);
};
});
};
});
return promise2;
};
resolvePromise(promise2, x, resolve, reject) {
if (promise2 === x) {
return reject(new TypeError('chaining cycle detected for promise'));
}
let called = false;
if (x !== null && (typeof x === 'function') || typeof x === 'object') {
try {
let then = x.then;
if (typeof then === 'function') {
then.call(x, (y) => {
if (called) return;
called = true;
this.resolvePromise(promise2, y, resolve, reject);
},(error) => {
if(called) return;
called = true;
reject(error);
})
}else{
resolve(x);
}
} catch (e) {
reject(e);
}
}else{
resolve(x);
}
};
};
const test3 = new myPromise((res,rej) => {
res(3);
});
test3.then((value) => {
console.log('value',value);
})
console