手写promise(3)-- 实例方法 && 静态方法

目录

实例方法

catch

finally

静态方法

reslove

 reject

race 

all 

allSettled

any


实例方法

提供给promise实例的方法 包括catch 与finally

catch

手写promise(3)-- 实例方法 && 静态方法_第1张图片

Promise 实例的 catch() 方法用于注册一个在 promise 被拒绝时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 的方法。此方法是 Promise.prototype.then(undefined, onRejected) 的一种简写形式。

1 内部调用then方法(此方法是 Promise.prototype.then(undefined, onRejected) 的一种简写形式。

2.处理异常 因为是实例化生成前抛出的异常 要 catch 捕获实例化生成函数执行前

   constructor(func) {
    const resolve = (result) => {
      if (this.state == PENDING) {
        this.state = FULFILLED;
        this.result = result;
        this.#handlers.forEach(({ onFulfilled }) => {
          onFulfilled(this.result);
        });
      }
    };

    const reject = (result) => {
      if (this.state == PENDING) {
        this.state = REJECTED;
        this.result = result;
        this.#handlers.forEach(({ onRejected }) => {
          onRejected(this.result);
        });
      }
    };

    try {
      func(resolve, reject);
    } catch (error) {
      reject(error);
    }
  }
 catch(onRejected) {
    return this.then(undefined, onRejected);
  }
// 测试代码

const p = new MyPromise((resolve, reject) => {
  reject("error");
  // throw "error";
  // return p2;
  // return 2;
  // return new MyPromise((resolve, reject) => {
  //   resolve("OK");
  //   // reject("ERROR");
  // });
});
p.then((res) => {
  console.log("res:", res);
}).catch((error) => {
  console.log("err:", err);
});

finally

Promise 实例的 finally() 方法用于注册一个在 promise 敲定(兑现或拒绝)时调用的函数。它会立即返回一个等效的 Promise 对象,这可以允许你链式调用其他 promise 方法。

手写promise(3)-- 实例方法 && 静态方法_第2张图片

finally() 方法类似于调用 then(onFinally, onFinally)

这可以让你避免在 promise 的 then() 和 catch() 处理器中重复编写代码。

  • onFinally 回调函数不接收任何参数。这种情况恰好适用于你不关心拒绝原因或兑现值的情况,因此无需提供它。
  • 如果你想在 promise 敲定时进行一些处理或者清理,无论其结果如何,那么 finally() 方法会很有用。
  finally(onFinally) {
    return this.then(onFinally, onFinally);
  }
const p = new MyPromise((resolve, reject) => {
  reject("error");
  // throw "error";
});
p.then((res) => {
  console.log("res:", res);
})
  .catch((error) => {
    console.log("err:", error);
  })
  .finally(() => {
    console.log("一定执行");
  });

静态方法

提供给promise静态的方法 包括以下6个

  • reslove
  • reject
  • race
  • all
  • allsettled
  • any

reslove

Promise.resolve() 静态方法将给定的值转换为一个 Promise。如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个 thenable 对象,Promise.resolve() 将调用其 then() 方法及其两个回调函数;否则,返回的 Promise 将会以该值兑现

  • 判断传入值
  • promise直接返回
  • 转为promise并返回  fulfilled状态

手写promise(3)-- 实例方法 && 静态方法_第3张图片

thenable对象指的是具有then方法的对象。Promise.resolve方法会将这个对象转为Promise对象,然后立即执行thenable对象的then方法

 /**
   * 静态方法 resolve
   *  判断传入值
   *    promise直接返回
   *    转为promise并返回  fulfilled状态
   */
  static resolve(value) {
    if (value instanceof MyPromise) {
      return value;
    }
    return new MyPromise((resolve, reject) => {
      resolve(value);
    });
  }

// 测试代码

// const p = MyPromise.resolve(
//   new MyPromise((resolve, reject) => {
//     resolve("ok");
//     // reject("error");
//     // throw "error";
//   })
// );
const p = MyPromise.resolve("贾公子");
p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

 reject

手写promise(3)-- 实例方法 && 静态方法_第4张图片

Promise.reject() 静态方法返回一个已拒绝(rejected)的 Promise 对象,拒绝原因为给定的参数。 

 static reject(value) {
    return new MyPromise((resolve, reject) => {
      reject(value);
    });
  }
// 测试代码
const p = MyPromise.reject("贾公子");
p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

race 

Promise.race() 静态方法接受一个 promise 可迭代对象作为输入,并返回一个 promise 这个返回的 promise 会随着第一个 promise 的敲定而敲定。

接收一个promise数组 返回的结果以第一个和promise返回的结果为准

* 返回promise

* 判断是否为数组(Array.isArray) 错误信息  Argument is not iterable

 * 等待第一个敲定 (forEach取出每一个promise执行 一旦执行就改变状态resolve包装一层 因为有可能传递的不是promise)

  /**
   * 静态方法 race
   * 返回promise
   * 判断是否为数组 错误信息  Argument is not iterable
   * 等待第一个敲定
   */
  static race(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.判断是否为数组 错误信息  Argument is not iterable
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }
      // 3.等待第一个敲定
      promises.forEach((p) => {
        MyPromise.resolve(p).then(
          (res) => resolve(res),
          (err) => reject(err)
        );
      });
    });
  }
}

// 测试代码

const p1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("ok");
  }, 2000);
});
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    reject("err");
  }, 1000);
});
const p = MyPromise.race([p1, p2]);
// const p = MyPromise.race();
p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

all 

 Promise.all() 静态方法接受一个 Promise 可迭代对象作为输入,并返回一个 Promise 。当所有输入的 Promise 都被兑现时,返回的 Promise 也将被兑现(即使传入的是一个空的可迭代对象),并返回一个包含所有兑现值的数组。如果输入的任何 Promise 被拒绝,则返回的 Promise 将被拒绝,并带有第一个被拒绝的原因。

  • 1.返回promise
  • 2.判断是否为数组 错误信息  Argument is not iterable
  • 3.空数组直接兑现
  • 4.判断全部兑现
  • 4.1记录结果(索引记录保证兑现顺序与传入顺序一样)
  • 4.2判断 全部兑现 (不能使用length 因为使用索引添加的可能导致没有全部兑现)
  • 5.处理第一个拒绝

手写promise(3)-- 实例方法 && 静态方法_第5张图片

  static all(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.判断是否为数组 错误信息  Argument is not iterable
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }

      // 3.空数组直接兑现
      promises.length === 0 && resolve(promises);
      // 4.判断全部兑现
      const result = [];
      let count = 0;
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          (res) => {
            // 4.1记录结果(索引记录保证兑现顺序与传入顺序一样)
            result[index] = res;
            // 4.2判断 全部兑现 (不能使用length 因为使用索引添加的可能导致没有全部兑现)
            count++;
            count === promises.length && resolve(result);
          },
          (err) => {
            // 5.处理第一个拒绝
            reject(err);
          }
        );
      });
    });
  }

// 测试代码
const p1 = MyPromise.resolve(1);
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err");
  }, 1000);
});
const p3 = "贾公子";
const p = MyPromise.all([p1, p2, p3]);
// const p = MyPromise.all();、
// const p = MyPromise.all([]);

p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

allSettled

Promise.allSettled() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个单独的 promise。当所有输入的 Promise 都已敲定时(包括传入空的可迭代对象时),返回的 Promise 将被兑现,并带有描述每个 Promise 结果的对象数组。

手写promise(3)-- 实例方法 && 静态方法_第6张图片

  * 1.传入的promise都已敲定,即可获取兑现结果

 *  2.结果数组: [{status: 'fulfilled', value: 1},{status: 'rejected', reason: 'err'}]

 *  3.结果数组的顺序,和传入的promise数组的顺序是一样的

 *  4.空数组直接兑现

 *  5.不为数组 错误信息  Argument is not iterable

  • 1.返回promise  可以让结果继续.then
  •  2.数组判断 不为数组直接抛出异常
  • 3.为空直接敲定  判断length
  • 4.等待全部敲定 使用forech 循环处理 利用resolve包装一下
  • 4.1记录结果(result) 记录敲定的次数(count) 不使用push 会导致没有全部兑现
  • 4.2 处理兑现{ status: FULFILLED, value: res }
  • 4.3处理拒绝{ status: REJECTED, reason: err })
  • 成功或者失败都是resolve
  static allSettled(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.数组判断
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }
      // 3.为空直接敲定
      promises.length === 0 && resolve(promises);
      // 4.等待全部敲定
      const result = [];
      let count = 0;
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          (res) => {
            // 4.1记录结果
            result[index] = { status: FULFILLED, value: res }; // 4.2 处理兑现{ status: FULFILLED, value: res }
            // 记录敲定的次数
            count++;
            // 不论成功失败都是resolve
            count === promises.length && resolve(result);
          },
          (err) => {
            // 4.1记录结果
            result[index] = { status: REJECTED, reason: err }; // 4.3处理拒绝{ status: REJECTED, reason: err }
            // 记录敲定的次数
            count++;
            // 不论成功失败都是resolve
            count === promises.length && resolve(result);
          }
        );
      });
    });
  }
// 测试代码
const p1 = MyPromise.resolve(1);
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err");
  }, 1000);
});
const p3 = "贾公子";
const p = MyPromise.allSettled([p1, p2, p3]);
// const p = MyPromise.allSettled();
// const p = MyPromise.allSettled([]);

p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    console.log("err:", error);
  }
);

any

Promise.any() 静态方法将一个 Promise 可迭代对象作为输入,并返回一个 promise 当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateErrorAggregateErrorAggregateError 拒绝。

AggregateError 对象代表了包装了多个错误对象的单个错误对象。当一个操作需要报告多个错误时,例如 promise.any,当传递给它的所有承诺都被拒绝时,就会抛出该错误。

 * 参数:promise数组

 * 结果

 *    获取到第一个成功的结果

 *    获取到所有拒绝失败的原因 AggregateError: All promises were rejected[拒绝原因1,拒绝原因n]

 *    传入空数组,直接拒绝 AggregateError: All promises were rejected[]

 *    不传入数组直接报错

手写promise(3)-- 实例方法 && 静态方法_第7张图片 

  • 1.返回promise 
  • 2.数组判断 错误信息 Argument is not iterable
  • 3.空数组直接拒绝 AggregateError([错误原因],All promises were rejected[)
  • 4.等待结果
  • 4.1第一个兑现
  • 4.2全部拒绝 
  static any(promises) {
    // 1.返回promise
    return new Promise((resolve, reject) => {
      // 2.数组判断 错误信息 Argument is not iterable
      if (!Array.isArray(promises)) {
        return reject(new TypeError("Argument is not iterable"));
      }
      // 3.空数组直接拒绝 AggregateError([错误原因],All promises were rejected[)
      promises.length === 0 &&
        reject(new AggregateError(promises, "All promises were rejected"));
      const errors = [];
      let count = 0;
      // 4.等待结果
      promises.forEach((p, index) => {
        MyPromise.resolve(p).then(
          (res) => {
            // 4.1第一个兑现
            resolve(res);
          },
          (err) => {
            // 4.2全部拒绝
            errors[index] = err;
            count++;
            count === promises.length &&
              reject(new AggregateError(errors, "All promises were rejected"));
          }
        );
      });
    });
  }
// 测试代码
const p1 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err1");
  }, 1000);
});
const p2 = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    // resolve("ok");
    reject("err2");
  }, 2000);
});
// const p3 = "贾公子";
const p3 = MyPromise.reject("贾公子");

const p = MyPromise.any([p1, p2, p3]);
// const p = MyPromise.any();
// const p = MyPromise.any([]);

p.then(
  (res) => {
    console.log("res:", res);
  },
  (error) => {
    // console.log("err:", error);
    console.dir(error);
  }
);

你可能感兴趣的:(javascript,前端,开发语言)