处理一般、异常、重复引用、resolve
<script>
function runAsyncTask(callback) {
if (typeof queueMicrotask === "function") {
queueMicrotask(callback);
} else if (typeof MutationObserver === "function") {
const obs = new MutationObserver(callback);
const divNode = document.createElement("div");
obs.observe(divNode, { childList: true });
divNode.innerText = "fx666";
} else {
setTimeout(callback, 0);
}
}
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";
class FXPromise {
state = PENDING;
result = undefined;
#handlers = [];
constructor(fn) {
const resolveFunc = (res) => {
if (this.state === PENDING) {
this.result = res;
this.state = FULFILLED;
this.#handlers.forEach(({ onFulfilled }) => {
onFulfilled(this.result);
});
}
};
const rejectFunc = (res) => {
if (this.state === PENDING) {
this.result = res;
this.state = REJECTED;
this.#handlers.forEach(({ onRejected }) => onRejected(this.result));
}
};
fn(resolveFunc, rejectFunc);
}
then(onFulfilled, onRejected) {
onFulfilled =
typeof onFulfilled === "function" ? onFulfilled : (x) => x;
onRejected =
typeof onRejected === "function"
? onRejected
: (x) => {
throw x;
};
const p2 = new FXPromise((resolve, reject) => {
if (this.state === FULFILLED) {
runAsyncTask(() => {
try {
const x = onFulfilled(this.result);
if (x === p2) {
throw new TypeError(
"Chaining cycle detected for promise #<Promise>"
);
}
if (x instanceof FXPromise) {
x.then(
(res) => resolve(res),
(err) => reject(err)
);
} else {
resolve(x);
}
} catch (error) {
reject(error);
}
});
} else if (this.state === REJECTED) {
runAsyncTask(() => {
onRejected(this.result);
});
} else if (this.state === PENDING) {
this.#handlers.push({
onFulfilled: (res) => {
runAsyncTask(() => {
onFulfilled(res);
});
},
onRejected: (res) => {
runAsyncTask(() => {
onRejected(res);
});
},
});
}
});
return p2;
}
}
const p = new FXPromise((resolve, reject) => {
resolve(1);
});
const p2 = p.then((res) => {
return p2;
});
p2.then(
(res) => {},
(err) => {
console.log("err:", err);
}
);
</script>