Skip to content

手写深拷贝和 Promise

深拷贝

js
function deepClone(obj, map = new Map()) {
  // return JSON.parse(JSON.stringify(obj))
  if (typeof obj !== "object" || obj === null) {
    return obj;
  }

  let copy = Array.isArray(obj) ? [] : {};

  if (map.get(obj)) {
    return map.get(obj);
  }

  map.set(obj, copy);

  if (Array.isArray(obj)) {
    for (let i = 0; i++; i < obj.length) {
      copy[i] = deepClone(obj[i]);
    }
  } else {
    for (let key in obj) {
      if (obj.hasOwnProperty(key)) {
        copy[key] = deepClone(obj[key], map);
      }
    }
  }

  return copy;
}

Promise

手写 promise

js
// 手写promise
class MyPromise {
  constructor(callback) {
    this.status = "pending";
    this.value = null;
    this.reason = null;

    this.onResolvedCallbacks = new Array();
    this.onRejectedCallbacks = new Array();

    this.resolve = (value) => {
      if (this.status === "pending") {
        this.value = value;
        this.status = "resolved";

        this.onResolvedCallbacks.map((cb) => cb());
      }
    };

    this.reject = (reason) => {
      if (this.status === "pending") {
        this.reason = reason;
        this.status = "rejected";

        this.onRejectedCallbacks.map((cb) => cb());
      }
    };

    callback(this.resolve, this.reject);
  }

  then(onResolve, onReject) {
    onResolve = typeof onResolve === "function" ? onResolve : (x) => x;
    onReject =
      typeof onReject === "function"
        ? onReject
        : (x) => {
            throw x;
          };

    const newPromise = new MyPromise((resolve, reject) => {
      if (this.status === "resolved") {
        try {
          const x = onResolve(this.value);
          resolve(x);
        } catch (err) {
          reject(err);
        }
      } else if (this.status === "rejected") {
        try {
          const x = onReject(this.reason);
          resolve(x);
        } catch (err) {
          reject(err);
        }
      }

      if (this.status === "pending") {
        this.onResolvedCallbacks.push(() => {
          if (this.status === "resolved") {
            try {
              const x = onResolve(this.value);
              resolve(x);
            } catch (err) {
              reject(err);
            }
          }
        });
        this.onRejectedCallbacks.push(() => {
          if (this.status === "rejected") {
            try {
              const x = onReject(this.reason);
              resolve(x);
            } catch (err) {
              reject(err);
            }
          }
        });
      } else {
        this.onRejectedCallbacks = [];
        this.onResolvedCallbacks = [];
      }
    });
    return newPromise;
  }

  catch = (onReject) => this.then(null, onReject);
}

手写 promise.all

js
// 手写 promise.all
const promiseAll = (values) => {
  const resArr = [];
  let orderIndex = 0;
  const promise = new Promise((resolve, reject) => {
    const addPromiseRes = (value, index) => {
      resArr[index] = value;
      if (++orderIndex === values.length) {
        resolve(resArr);
      }
    };
    for (let i = 0; i < values.length; i++) {
      if (values[i] && typeof values[i].then === "function") {
        values[i].then((res) => {
          addPromiseRes(res, i);
        }, reject);
      } else {
        addPromiseRes(values[i], i);
      }
    }
  });
  return promise;
};

手写 promise.race 并封装中断

js
// 手写promise.race 并封装中断
const promiseRace = (values) => {
  const promise = new Promise((resolve, reject) => {
    for (let i = 0; i < values.length; i++) {
      values[i].then((res) => {
        resolve(res);
      }, reject);
    }
  });
  return promise;
};

const wrap = (fn) => {
  let abort;
  const newPromise = new Promise((_, reject) => {
    abort = reject;
  });
  const p = promiseRace([fn, newPromise]);
  p.abort = abort;
  return p;
};

手写 promisefy

js
// 手写 promisefy
const promisefy = (fn) => {
  return (...args) => {
    return new Promise((resolve, reject) => {
      fn(...args, function (err, data) {
        // node中的回调函数的参数 第一个永远是error
        if (err) return reject(err);
        resolve(data);
      });
    });
  };
};

备案号:闽ICP备2024028309号-1