const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
function runMicroTask(callback) {
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 = "a";
}
else {
setTimeout(callback, 0);
}
}
function isPromise(obj) {
return !!(obj && typeof obj === "object" && typeof obj.then === "function");
}
class MyPromise {
constructor(executor) {
this.__status = PENDING;
this.__value = undefined;
this.__handlers = [];
try {
executor(this.__resolve.bind(this), this.__reject.bind(this));
} catch (error) {
this.__reject(error);
}
}
__resolve(data) {
this.__changeState(FULFILLED, data);
}
__reject(reason) {
this.__changeState(REJECTED, reason);
}
__changeState(newStatus, newValue) {
if (this.__status !== PENDING) {
return;
}
this.__status = newStatus;
this.__value = newValue;
this.__runHandlers();
}
then(onFulfilled, onRejected) {
return new MyPromise((resolve, reject) => {
this.__pushHandlers(onFulfilled, FULFILLED, resolve, reject);
this.__pushHandlers(onRejected, REJECTED, resolve, reject);
this.__runHandlers();
});
}
__pushHandlers(executor, status, resolve, reject) {
this.__handlers.push({
executor,
status,
resolve,
reject,
});
}
__runHandlers() {
if (this.__status === PENDING) {
return;
}
while (this.__handlers[0]) {
this.__runOneHandler(this.__handlers[0]);
this.__handlers.shift();
}
}
__runOneHandler({ executor, status, resolve, reject }) {
runMicroTask(() => {
if (status !== this.__status) return;
if (typeof executor !== "function") {
this.__status === FULFILLED
? resolve(this.__value)
: reject(this.__value);
}
try {
const result = executor(this.__value);
if (isPromise(result)) {
result.then(resolve, reject);
} else {
resolve(result);
}
} catch (error) {
reject(error);
}
});
}
}