Promise 微任务的实现(五)

114 阅读1分钟

模拟微任务的实现

  1. 微任务的模拟实现 queueMicrotask 、MutationObserver、setImmediate【该特性是非标准的,不要在生产环境中使用它】、setTimeout兜底
  2. 我们选用 queueMicrotask 、MutationObserver、setTimeout。考虑到兼容性,setTimeout兜底
  console.log("1");
    queueMicrotask(() => {
      console.log("queueMicrotask");
    });
    console.log("2");
   console.log("1");
    // 1. 创建观察器,并传入回调函数
    const obs = new MutationObserver(() => {
      console.log("MutationObserver");
    });
    // 2. 创建元素,并添加监听
    const divNode = document.createElement("div");
    // 参数1 观察的dom节点
    // 参数2 观察的选项(childList 观察子节点改变)
    obs.observe(divNode, { childList: true });
    // 3. 修改元素内容
    divNode.innerText = "itheima 666";
    console.log("2");

实现Promise的微任务

 <script>
    //  1. 模拟微任务
    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 resolve = (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(resolve, rejectFunc);
      }

      then(onFulfilled, onRejected) {
        onFulfilled =
          typeof onFulfilled === "function" ? onFulfilled : (x) => x;
        onRejected =
          typeof onRejected === "function"
            ? onRejected
            : (x) => {
                throw x;
              };
        if (this.state === FULFILLED) {
          // 2. 回调在微任务中执行
          runAsyncTask(() => {
            onFulfilled(this.result);
          });
        } else if (this.state === REJECTED) {
          // 2. 回调在微任务中执行
          runAsyncTask(() => {
            onRejected(this.result);
          });
        } else if (this.state === PENDING) {
          // 2. 保存回调函数   回调在微任务中执行
          this.#handlers.push({
            onFulfilled: (res) => {
              runAsyncTask(() => {
                onFulfilled(res);
              });
            },
            onRejected: (res) => {
              runAsyncTask(() => {
                onRejected(res);
              });
            },
          });
        }
      }
    }

    console.log(1);
    const p = new FXPromise((resolve, reject) => {
      resolve("resolve");
    });
    p.then(
      (res) => {
        console.log("then res ", res);
      },
      (err) => {
        console.log("then err ", err);
      }
    );
    console.log(2);
  </script>

image.png