目录
实例方法
catch
finally
静态方法
reslove
reject
race
all
allSettled
any
提供给promise实例的方法 包括catch 与finally
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);
});
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个
Promise.resolve() 静态方法将给定的值转换为一个 Promise。如果该值本身就是一个 Promise,那么该 Promise 将被返回;如果该值是一个 thenable 对象,Promise.resolve() 将调用其 then() 方法及其两个回调函数;否则,返回的 Promise 将会以该值兑现
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);
}
);
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 将被拒绝,并带有第一个被拒绝的原因。
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);
}
);
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
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);
}
);
Promise.any()
静态方法将一个 Promise 可迭代对象作为输入,并返回一个 promise 当输入的任何一个 Promise 兑现时,这个返回的 Promise 将会兑现,并返回第一个兑现的值。当所有输入 Promise 都被拒绝(包括传递了空的可迭代对象)时,它会以一个包含拒绝原因数组的 AggregateErrorAggregateErrorAggregateError 拒绝。
AggregateError
对象代表了包装了多个错误对象的单个错误对象。当一个操作需要报告多个错误时,例如 promise.any,当传递给它的所有承诺都被拒绝时,就会抛出该错误。
* 参数:promise数组
* 结果
* 获取到第一个成功的结果
* 获取到所有拒绝失败的原因 AggregateError: All promises were rejected[拒绝原因1,拒绝原因n]
* 传入空数组,直接拒绝 AggregateError: All promises were rejected[]
* 不传入数组直接报错
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);
}
);