目录
实例方法
catch
finally
静态方法
reslove
reject
race
all
allSettled
any
实例方法
提供给promise实例的方法 包括catch 与finally
catch
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 方法。
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状态
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.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.返回promisereturn new Promise((resolve, reject) => {// 2.判断是否为数组 错误信息 Argument is not iterableif (!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.处理第一个拒绝
static all(promises) {// 1.返回promisereturn new Promise((resolve, reject) => {// 2.判断是否为数组 错误信息 Argument is not iterableif (!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 结果的对象数组。
* 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.返回promisereturn 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++;// 不论成功失败都是resolvecount === promises.length && resolve(result);},(err) => {// 4.1记录结果result[index] = { status: REJECTED, reason: err }; // 4.3处理拒绝{ status: REJECTED, reason: err }// 记录敲定的次数count++;// 不论成功失败都是resolvecount === 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[]
* 不传入数组直接报错
- 1.返回promise
- 2.数组判断 错误信息 Argument is not iterable
- 3.空数组直接拒绝 AggregateError([错误原因],All promises were rejected[)
- 4.等待结果
- 4.1第一个兑现
- 4.2全部拒绝
static any(promises) {// 1.返回promisereturn new Promise((resolve, reject) => {// 2.数组判断 错误信息 Argument is not iterableif (!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);}
);