ES6笔记 22.Promise重写

Promise 重写

重写过程 MyPromise

  1. new Promise((resolve, reject) 中执行器函数立即执行,所以将 executor 函数放在类 MyPromise 的构造器函数中并且立即执行,同时,给出 promise 的三个状态常量
const PENDING = "PENDING",
  FULFILLED = "FULFILLED",
  REJECTED = "REJECTED";
class MyPromise {
  constructor(executor) {
    executor(resolve, reject);
  }
}
  1. 一个 promise 初始状态为 pending,同时 resolve 和 reject 函数的方法参数不确定
class MyPromise {
  constructor(executor) {
    this.status = PENDING;
    this.value = undefined;
    this.reason = undefined;
    executor(resolve, reject);
  }
}
  1. 构造器函数中声明 resolve 和 reject 保证每次使用的都是独立的函数, 并且函数中只有 pengding 状态才可以执行函数,同时将传进来的值给到实例对象
constructor(executor) {
  // 给上初始状态PENDING
  this.status = PENDING;
  // 函数 resolve 和 reject 参数默认值给undefined
  this.value = undefined;
  this.reason = undefined;

  const resolve = (value) => {
    if (this.status == PENDING) {
      this.status = FULFILLED;
      this.value = value;
    }
  }
  const reject = (reason) => {
    if (this.status == PENDING) {
      this.status = REJECTED;
      this.reason = reason;
    }
  }

  executor(resolve, reject);
}
  1. 在类中写一个原型上的方法 then , 根据状态执行对应的方法, 同时使用实例对象上的属性 this.value
class MyPromise {
  // 构造器函数中声明 resolve 和 reject 保证每次使用的都是独立的函数
  constructor(executor) {
    // 给上初始状态PENDING
    this.status = PENDING;
    // 函数 resolve 和 reject 参数默认值给undefined
    this.value = undefined;
    this.reason = undefined;

    const resolve = (value) => {
      // 只有 pengding 状态才可以执行
      if (this.status == PENDING) {
        this.status = FULFILLED;
        this.value = value;
      }
    };
    const reject = (reason) => {
      // 只有 pengding 状态才可以执行
      if (this.status == PENDING) {
        this.status = REJECTED;
        this.reason = reason;
      }
    };

    executor(resolve, reject);
  }

  // 直接写在原型上的 then 方法中根据状态执行对应的方法, 同时使用实例对象上的属性 this.value
  then(onFulfilled, onRejected) {
    if (this.status === FULFILLED) {
      onFulfilled(this.value);
    }

    if (this.status === REJECTED) {
      onRejected(this.reason);
    }
  }
}
  1. 在抛出错误时会出现错误, 要用 try…catch 包裹一下
constructor(executor) {
  // 给上初始状态PENDING
  this.status = PENDING;
  // 函数 resolve 和 reject 参数默认值给undefined
  this.value = undefined;
  this.reason = undefined;

  const resolve = (value) => {
    // 只有 pengding 状态才可以执行
    if (this.status == PENDING) {
      this.status = FULFILLED;
      this.value = value;
    }
  }
  const reject = (reason) => {
    // 只有 pengding 状态才可以执行
    if (this.status == PENDING) {
      this.status = REJECTED;
      this.reason = reason;
    }
  }

  // 出现错误就直接执行 reject 函数
  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e)
  }
}
  1. 当执行器函数中出现异步情况时, 如果 resolve 或者 reject 函数异步执行, 当执行到 then 方法时会是 pending 状态, 此时无法正常执行回调函数, 为了解决这个问题, 在构造器中设置两个容器, 分别用来存放成功的回调和失败的回调, 使用发布-订阅模式来先收集所有的等待执行函数, 等到 then 也执行完毕后再执行相应的 resolve 或者 reject 函数
class MyPromise {
  // 构造器函数中声明 resolve 和 reject 保证每次使用的都是独立的函数
  constructor(executor) {
    // 给上初始状态PENDING
    this.status = PENDING;
    // 函数 resolve 和 reject 参数默认值给undefined
    this.value = undefined;
    this.reason = undefined;

    // 设置两个容器, 分别用来存放成功的回调函数和失败的回调函数
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      // 只有 pengding 状态才可以执行
      if (this.status == PENDING) {
        this.status = FULFILLED;
        this.value = value;
        // 发布
        this.onFulfilledCallbacks.forEach((fn) => fn());
      }
    };
    const reject = (reason) => {
      // 只有 pengding 状态才可以执行
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        // 发布
        this.onRejectedCallbacks.forEach((fn) => fn());
      }
    };

    // 出现错误就直接执行 reject 函数
    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e);
    }
  }

  // 直接写在原型上的 then 方法中根据状态执行对应的方法, 同时使用实例对象上的属性 this.value
  then(onFulfilled, onRejected) {
    if (this.status === FULFILLED) {
      onFulfilled(this.value);
    }

    if (this.status === REJECTED) {
      onRejected(this.reason);
    }

    if (this.status === PENDING) {
      // 订阅
      this.onFulfilledCallbacks.push(() => {
        onFulfilled(this.value);
      });
      this.onRejectedCallbacks.push(() => {
        onRejected(this.reason);
      });
    }
  }
}

let promise = new MyPromise((resolve, reject) => {
  // resolve('success')
  // reject('error')
  // throw new Error('exception: error')

  setTimeout(() => {
    resolve("success 2");
  }, 2000);
});
promise.then(
  (value) => {
    console.log("value1", value);
  },
  (reason) => {
    console.log("reason1", reason);
  }
);

promise.then(
  (value) => {
    console.log("value2", value);
  },
  (reason) => {
    console.log("reason2", reason);
  }
);

promise 的链式调用

  • 链式调用的结果由 return 决定
let p = new Promise((resolve, reject) => {
  resolve("hello");
});

p.then((res) => {
  return "world";
}).then((res) => {
  console.log(res); // world
});
  • 通过 return 新的 Promise 来决定传递值
let p = new Promise((resolve, reject) => {
  resolve("hello");
});

p.then((value) => {
  return new Promise((resolve, reject) => {
    resolve("world");
  });
}).then((value) => {
  console.log(value); // world
});
let p = new Promise((resolve, reject) => {
  resolve("hello");
});

p.then((value) => {
  return new Promise((resolve, reject) => {
    reject("error");
  });
}).then(
  (value) => {
    console.log("value", value);
  },
  (reason) => {
    console.log("reason", reason); // reason error
  }
);
  • 链式调用中没有 return 返回值则默认返回 undefined 并且再下一次链式调用中默认走 onFulfilled 方法
let p = new Promise((resolve, reject) => {
  resolve("hello");
});

p.then((value) => {
  return new Promise((resolve, reject) => {
    reject("error");
  });
})
  .then(
    (value) => {
      console.log("value", value);
    },
    (reason) => {
      console.log("reason", reason); // reason error
      // 无返回值默认 return undefined;
    }
  )
  .then(
    (value) => {
      console.log("---", value); // --- undefined
    },
    (reason) => {
      console.log("+++", reason);
    }
  );
  • 在 then 中抛出错误会在下一次链式调用的 onRejected 方法
let p = new Promise((resolve, reject) => {
  resolve("hello");
});

p.then((value) => {
  throw new Error("throw error");
}).then(
  (value) => {
    console.log("---", value);
  },
  (reason) => {
    console.log("+++", reason); // +++ throw error
  }
);
  • 链式调用使用 onRejected 和 catch 捕获异常,哪个离得近就被哪个捕获到
let p = new Promise((resolve, reject) => {
  resolve("hello");
});

p.then((value) => {
  throw new Error("throw error");
})
  .then(
    (value) => {
      console.log("---", value); // --- undefined
    },
    (reason) => {
      console.log("then", reason); // then Error: throw error
    }
  )
  .catch((err) => {
    console.log("+++", err);
  });
  • 在 catch 后继续链式调用可以获取到 catch 返回的值, 和正常的一样, 成功走 onFulfilled 方法, 失败走 onRejected 方法
let p = new Promise((resolve, reject) => {
  resolve("hello");
});

p.then((value) => {
  throw new Error("throw error");
})
  .then((value) => {
    console.log("---", value); // --- undefined
  })
  .catch((err) => {
    console.log("+++", err); // +++ Error: throw error
    return "catch msg";
  })
  .then(
    (value) => {
      console.log("111", value); // 111 catch msg
    },
    (reason) => {
      console.log("222", reason);
    }
  );

链式调用中成功的条件
then return 普通的 JavaScript value
then return 新的 promise 成功态的结果 value

失败的条件
then return 新的 promise 失败态的原因 reason
then 抛出了异常 throw new Error

promise 能够链式调用的原理和实现

原理: 每一次的链式调用都会返回一个新的 promise 对象

class MyPromise {
  // 构造器函数中声明 resolve 和 reject 保证每次使用的都是独立的函数
  constructor(executor) {
    // 给上初始状态PENDING
    this.status = PENDING;
    // 函数 resolve 和 reject 参数默认值给undefined
    this.value = undefined;
    this.reason = undefined;

    // 设置两个容器, 分别用来存放成功的回调函数和失败的回调函数
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      // 只有 pengding 状态才可以执行
      if (this.status == PENDING) {
        this.status = FULFILLED;
        this.value = value;
        // 发布
        this.onFulfilledCallbacks.forEach((fn) => fn());
      }
    };
    const reject = (reason) => {
      // 只有 pengding 状态才可以执行
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        // 发布
        this.onRejectedCallbacks.forEach((fn) => fn());
      }
    };

    // 出现错误就直接执行 reject 函数
    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e);
    }
  }

  // 直接写在原型上的 then 方法中根据状态执行对应的方法, 同时使用实例对象上的属性 this.value
  then(onFulfilled, onRejected) {
    // 给出默认值, then 中没有参数时就当他为一个以参数传值的函数
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };
    let promise2 = new MyPromise((resolve, reject) => {
      if (this.status === FULFILLED) {
        // 为了能够对 x 值进行处理, 由于函数执行完毕之前获取不到 promise2 ,所以这里使用异步
        setTimeout(() => {
          try {
            // 完成一个成功或者失败函数返回一个值, 通过对这个值进行处理来返回一个新的promise
            let x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      }

      if (this.status === REJECTED) {
        setTimeout(() => {
          try {
            let x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      }

      if (this.status === PENDING) {
        // 订阅
        this.onFulfilledCallbacks.push(() => {
          try {
            let x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
        this.onRejectedCallbacks.push(() => {
          try {
            let x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      }
    });

    return promise2;
  }

  catch(errCallback) {
    return this.then(null, errCallback);
  }
}

function resolvePromise(promise2, x, resolve, reject) {
  // 规范一: promise2 和 x 不能指向相同的对象, 即在链式调用中, 如果第一次then的返回值是被赋值的本身, 那显然是错误的
  if (promise2 === x) {
    return reject(
      new TypeError(
        "then方法返回的promise和在then中进行resolve或者reject后返回的x不能指向同一个对象"
      )
    );
  }

  // 规范三: 如果 resolve 和 reject 被重复多次调用, 只执行第一次后面的忽略
  let called = false;

  // 规范三: 对于返回来的 x 值的类型的判定, 如果是一个对象或者函数, 还需要判断 x 中的 then 属性的类型, 如果 then 是一个函数, 那么就认定 x 为一个 promise(MyPromise) 对象; 如果不是一个函数, 那么认定 x 不为一个 promise(MyPromise) 对象, 直接调用 resolve 方法
  if ((typeof x === "object" && x !== null) || typeof x === "function") {
    // 考虑到可能对象被 defineProperty 修改过 get 操作从而抛出错误, 使用try...catch包裹
    try {
      let then = x.then;
      if (typeof then === "function") {
        then.call(
          x,
          (y) => {
            if (called) return;
            called = true;
            // 当发送的是一个 promise 对象时, 会再继续找到其中的 resolve 中真正的值
            resolvePromise(promise2, y, resolve, reject);
          },
          (r) => {
            if (called) return;
            called = true;
            reject(r);
          }
        );
      } else {
        resolve(x);
      }
    } catch (e) {
      if (called) return;
      called = true;
      reject(e);
    }
  } else {
    resolve(x);
  }
}

resolve 函数中的实参仍是 MyPromise 对象时,需要对 then 方法中获取到的 value 进行判断

constructor(executor) {
  // 给上初始状态PENDING
  this.status = PENDING;
  // 函数 resolve 和 reject 参数默认值给 undefined
  this.value = undefined;
  this.reason = undefined;

  // 设置两个容器, 分别用来存放成功的回调函数和失败的回调函数
  this.onFulfilledCallbacks = [];
  this.onRejectedCallbacks = [];

  const resolve = (value) => {
    // 如果这里传进来的是一个 MyPromise 对象
    if (value instanceof MyPromise) {
      value.then(resolve, reject)
      return;
    }

    // 只有 pengding 状态才可以执行
    if (this.status == PENDING) {
      this.status = FULFILLED;
      this.value = value;
      // 发布
      this.onFulfilledCallbacks.forEach(fn => fn());
    }
  }
  const reject = (reason) => {
    // 只有 pengding 状态才可以执行
    if (this.status === PENDING) {
      this.status = REJECTED;
      this.reason = reason;
      // 发布
      this.onRejectedCallbacks.forEach(fn => fn());
    }
  }

  // 出现错误就直接执行 reject 函数
  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e)
  }
}

完成静态方法 resolve 和 reject

// 静态方法
static resolve(value) {
  return new MyPromise((resolve, reject) => {
    resolve(value)
  })
}

static reject(error) {
  return new MyPromise((resolve, reject) => {
    reject(error)
  })
}

完成 MyPromise.all() 方法

设计思路:

  • 一个静态方法
  • 接受数据是一个数组, 数组中可能出现 MyPromise 也可能出现普通数据, 针对不同进行处理
static all(promiseArr) {
  // 使用 idx 记录数量值是因为当数组中不在第一位的数据出现时, 前面的位置会出现 empty 空数据, 如果使用 resArr.length 就会不准
  let resArr = [],
    idx = 0;
  return new MyPromise((resolve, reject) => {
    promiseArr.map((promise, index) => {
      if (isPromise(promise)) {
        promise.then((res) => {
          formatResArr(res, index, resolve);
        }, reject)
      } else {
        formatResArr(promise, index, resolve);
      }
    })
  })

  function formatResArr(value, index, resolve) {
    resArr[index] = value;

    if (++idx === promiseArr.length) {
      resolve(resArr)
    }
  }

  function isPromise(x) {
    if ((typeof x === 'object' && x !== null) || typeof (x) === 'function') {
      let then = x.then;
      return typeof then === 'function';
    }
    return false
  }
}
function getP(val, delay = 0) {
  return new MyPromise((resolve, reject) => {
    if (delay) {
      setTimeout(() => {
        resolve(val);
      }, delay);
    } else {
      resolve(val);
    }
  });
}

let pp1 = getP(123);
let pp2 = getP("shaoyahu", 2000);
let pp3 = getP([1, 2, 3]);
let pp4 = getP({ name: "shaoyahu" });

let pp = MyPromise.all([pp1, pp2, pp3, pp4, "zhangsan"]);
pp.then((res) => console.log(res));

完成 MyPromise.allSettled() 方法

将 isPromise 方法提到外面去一起使用

class MyPromise {
  // 构造器函数中声明 resolve 和 reject 保证每次使用的都是独立的函数
  constructor(executor) {
    // 给上初始状态PENDING
    this.status = PENDING;
    // 函数 resolve 和 reject 参数默认值给undefined
    this.value = undefined;
    this.reason = undefined;

    // 设置两个容器, 分别用来存放成功的回调函数和失败的回调函数
    this.onFulfilledCallbacks = [];
    this.onRejectedCallbacks = [];

    const resolve = (value) => {
      // 如果这里传进来的是一个 MyPromise 对象
      if (value instanceof MyPromise) {
        value.then(resolve, reject);
        return;
      }

      // 只有 pengding 状态才可以执行
      if (this.status == PENDING) {
        this.status = FULFILLED;
        this.value = value;
        // 发布
        this.onFulfilledCallbacks.forEach((fn) => fn());
      }
    };
    const reject = (reason) => {
      // 只有 pengding 状态才可以执行
      if (this.status === PENDING) {
        this.status = REJECTED;
        this.reason = reason;
        // 发布
        this.onRejectedCallbacks.forEach((fn) => fn());
      }
    };

    // 出现错误就直接执行 reject 函数
    try {
      executor(resolve, reject);
    } catch (e) {
      reject(e);
    }
  }

  // 直接写在原型上的 then 方法中根据状态执行对应的方法, 同时使用实例对象上的属性 this.value
  then(onFulfilled, onRejected) {
    // 给出默认值, then 中没有参数时就当他为一个以参数传值的函数
    onFulfilled =
      typeof onFulfilled === "function" ? onFulfilled : (value) => value;
    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (reason) => {
            throw reason;
          };
    let promise2 = new MyPromise((resolve, reject) => {
      if (this.status === FULFILLED) {
        // 为了能够对 x 值进行处理, 由于函数执行完毕之前获取不到 promise2 ,所以这里使用异步
        setTimeout(() => {
          try {
            // 完成一个成功或者失败函数返回一个值,通过对这个值进行处理来返回一个新的promise
            let x = onFulfilled(this.value);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      }

      if (this.status === REJECTED) {
        setTimeout(() => {
          try {
            let x = onRejected(this.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        });
      }

      if (this.status === PENDING) {
        // 订阅
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onFulfilled(this.value);
              resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0);
        });
        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              let x = onRejected(this.reason);
              resolvePromise(promise2, x, resolve, reject);
            } catch (e) {
              reject(e);
            }
          }, 0);
        });
      }
    });

    return promise2;
  }

  catch(errCallback) {
    return this.then(null, errCallback);
  }

  // 静态方法
  static resolve(value) {
    return new MyPromise((resolve, reject) => {
      resolve(value);
    });
  }

  static reject(error) {
    return new MyPromise((resolve, reject) => {
      reject(error);
    });
  }

  static all(promiseArr) {
    // 使用 idx 记录数量值是因为当数组中不在第一位的数据出现时, 前面的位置会出现 empty 空数据, 如果使用 resArr.length 就会不准
    let resArr = [],
      idx = 0;
    return new MyPromise((resolve, reject) => {
      promiseArr.map((promise, index) => {
        if (isPromise(promise)) {
          promise.then((res) => {
            formatResArr(res, index, resolve);
          }, reject);
        } else {
          formatResArr(promise, index, resolve);
        }
      });
    });

    function formatResArr(value, index, resolve) {
      resArr[index] = value;

      // 等所有 promise 都执行完毕了就 resolve 回原来的数组
      if (++idx === promiseArr.length) {
        resolve(resArr);
      }
    }
  }

  static allSettled(promiseArr) {
    let resArr = [],
      idx = 0;
    // 判断一下传入的值是不是一个可迭代对象
    if (!isIterable(promiseArr)) {
      throw new TypeError(`${promiseArr}不是一个可迭代对象`);
    }

    return new MyPromise((resolve, reject) => {
      if (promiseArr.length === 0) {
        resolve([]);
      }

      // 对每一个 promise 都进行执行, 成功或者失败返回相类似的格式就行, 执行的方法还是由传入决定
      promiseArr.map((promise, index) => {
        if (isPromise(promise)) {
          promise.then(
            (value) => {
              formatResArr("fulfilled", value, index, resolve);
            },
            (reason) => {
              formatResArr("rejected", reason, index, resolve);
            }
          );
        } else {
          formatResArr("fulfilled", promise, index, resolve);
        }
      });
    });

    function formatResArr(status, value, index, resolve) {
      switch (status) {
        case "fulfilled":
          resArr[index] = {
            status,
            value,
          };
          break;
        case "rejected":
          resArr[index] = {
            status,
            reason: value,
          };
          break;
        default:
          break;
      }

      // 等所有 promise 都执行完毕了就 resolve 回原来的数组
      if (++idx === promiseArr.length) {
        resolve(resArr);
      }
    }
  }
}

function isPromise(x) {
  if ((typeof x === "object" && x !== null) || typeof x === "function") {
    let then = x.then;
    return typeof then === "function";
  }
  return false;
}

function isIterable(value) {
  return (
    value !== null &&
    value !== undefined &&
    typeof value[Symbol.iterator] === "function"
  );
}
function getP(val, delay = 0) {
  return new MyPromise((resolve, reject) => {
    if (delay) {
      setTimeout(() => {
        resolve(val);
      }, delay);
    } else {
      resolve(val);
    }
  });
}
let pp5 = new MyPromise((resolve, reject) => {
  reject("lisi");
});

let pp1 = getP(123);
let pp2 = getP("shaoyahu", 2000);

let pp = MyPromise.allSettled([pp1, pp2, pp5, "zhangsan"]);
pp.then((res) => console.log(res));

完成 MyPromise.race() 方法

一共只有一个新的 promise, 在新 promise 中对数组中每个 promise 直接传入新 promise 的 resolve 和 reject 方法,当一个被触发时,新的 promise 就结束了,所以其他的 promise 就不会在继续了

static race(promiseArr) {
  return new MyPromise((resolve, reject) => {
    promiseArr.map((promise) => {
      //按照顺序一个一个来进行 then ,该怎么执行怎么执行, 只要有一个结束了, 当前这个新 new 出来的 MyPromise 对象就直接执行相应的 resolve 或者 reject 方法结束掉所有 promise
      if (isPromise(promise)) {
        // 该怎么执行怎么执行
        promise.then(resolve, reject);
      } else {
        resolve(promise);
      }
    })
  })
}

完成 MyPromise.finally() 方法

finally() 特点

  1. 无论外面的 promise 成功还是失败都要走, 并且回调不带参数
  2. 正常走 finally 之后的 then 或者 catch
  3. 如果 finally 内部有 promise并且有延时处理, 整个 finally 会等待
  4. 如果两个都是成功, 取外面的成功的结果
  5. 如果两个都是失败, 取里面失败的结果
  6. 如果外面是成功, 里面是失败, 取里面的失败的结果
  7. 如果外面是失败, 里面是成功, 取外面失败的结果
Promise.resolve("promsie resolve")
  .finally(() => {
    console.log("finally");
    return new Promsie((resolve, reject) => {
      setTimeout(() => {
        reject("new Promise errer");
      });
    });
  })
  .then((res) => {
    console.log("success:" + res);
  })
  .catch((err) => {
    console.log("catch:" + err);
  });

重写

finally(finallyCallback) {
  return this.then((value) => {
    // 外面成功
    // 1.里面成功, 直接走 then 将外面成功的 value 传给下一个 then
    // 2.里面失败, finallyCallback 方法中失败, 直接被最外面的 catch 捕获到输出里面的失败结果
    return MyPromise.resolve(finallyCallback()).then(() => value)
  }, (reason) => {
    // 外面失败
    // 1.里面成功, 直接抛出外面的错误 reason 到最外面的 catch 中被捕获
    // 2.里面失败, finallyCallback 方法中失败, 直接被最外面的 catch 捕获到输出里面的失败结果
    return MyPromise.resolve(finallyCallback()).then(() => {
      throw reason
    })
  })
}

实现 promisify

一个方法, 返回的是一个 promise 对象, 需要使用 then 来获取成功的数据
直接包裹住就好了

static promisify(fn) {
  return (...args) => {
    return new MyPromise((resolve, reject) => {
      fn(...args, (error, data) => {
        if (error) {
          return reject(error)
        }
        resolve(data)
      })
    })
  }
}
const fs = require("fs");
const MyPromise = require("./MyPromise");
const read = MyPromise.promisify(fs.readFile);
read("../测试文本文件/one.txt", "utf-8").then((res) => console.log(res));

实现 promisifyAll

就是使用 promisify 方法用遍历将一个集合中的所有都包一层

static promisifyAll(fns) {
  Object.keys(fns).map(fnName => {
    if (typeof (fns[fnName] === 'function')) {
      fns[fnName + 'Async'] = MyPromise.promisify(fns[fnName]);
    }
  })
  return fns;
}
const fs = require("fs");
const MyPromise = require("./MyPromise");
const fsAsync = MyPromise.promisifyAll(fs);
fsAsync
  .readFileAsync("../测试文本文件/one.txt", "utf-8")
  .then((res) => console.log(res));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值