如果可以实现记得点赞分享,谢谢老铁~
Promise在 JavaScript 中并不是一个新概念。它们是表示异步操作的最终完成或失败及其结果值的对象。
Promise 有三种可能的状态:pending – 初始状态(仍在等待)、已完成– Promise 成功、Rejected – Promise 失败。如果承诺被履行或被拒绝,但没有悬而未决,则该承诺被称为已解决。
Promise 组合器用于更轻松地处理 Promise。JavaScript 有四个 Promise 组合器,但它们处于 ECMAScript 的不同阶段。
Promise.all()
Promise.all() 是一种接受可迭代的 Promise 对象并返回单个 Promise 的方法。如果所有的承诺都得到履行,则返回的承诺也得到履行。
const P1 = Promise.resolve(18);
const P2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(5);
}, 100);
});
const P3 = Promise.resolve("18.5.");
const promises = [P1, P2, P3];
Promise.all(promises).then((values) => {
console.log(values);
});
//Array [18, 5, "18.5."]
或者,使用异步/等待:
async function f() {
const P1 = Promise.resolve(18);
const P2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve(5);
}, 100);
});
const P3 = Promise.resolve("18.5.");
const promises = [P1, P2, P3];
try {
const result = await Promise.all(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //Array [18, 5, "18.5."]
即使第二个 Promise 花费了最长的时间来解决,返回的 Promise 中的顺序将始终与其源 Promise 中的顺序保持不变。
如果传递一个空对象,那么它返回一个已经解析的 Promise。
Promise.all() 也接受非 Promise 值并按原样返回它们。
async function f() {
const promises = [1, 2, 3];
try {
const result = await Promise.all(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //Array [1, 2, 3]
如果至少有一个 Promise 被拒绝,则返回的 Promise 被拒绝。该错误成为整个 Promise.all() 方法的结果。其他承诺的结果被完全忽略。
async function f() {
const P1 = Promise.resolve(18);
const P2 = Promise.resolve(5);
const P3 = new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("Error happened!"));
}, 200);
});
const promises = [P1, P2, P3];
try {
const result = await Promise.all(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //Error: Error happened!
自 ES2015 中引入 Promise 以来,Promise.all() 就成为了 JavaScript 的一部分,同时还添加了一种 Promise 静态方法:Promise.race()
Promise.race()
Promise.race() 从收到的可迭代 Promise 对象中返回第一个已解决的 Promise。那就可以兑现诺言了。
async function f() {
const P1 = Promise.resolve(18);
const P2 = Promise.resolve(5);
const P3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("18.5.");
}, 100);
});
const promises = [P1, P2, P3];
try {
const result = await Promise.race(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //18
或者它可能是一个被拒绝的 Promise。
async function f() {
const P1 = Promise.reject(new Error("Error happened!"));
const P2 = Promise.resolve(5);
const P3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("18.5.");
}, 100);
});
const promises = [P1, P2, P3];
try {
const result = await Promise.race(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //Error: Error happened!
如果传递一个空对象,则返回的 Promise 将永远挂起。
如果 Promise.race() 接收到非 Promise 值,它将解析为可迭代中找到的第一个值。
async function f() {
const promises = [1, 2, 3];
try {
const result = await Promise.race(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //1
Promise.allSettled()
最后的ES2020中添加了 Promise.allSettled() 方法。旧的浏览器可能仍然需要腻子来支持它。此方法等待所有收到的承诺结算。它返回一个 Promise:
- { status: “fulfilled”, value: result } 表示成功响应或
- { status: “rejected”, Reason: error} 对于有错误的响应。
async function f() {
const P1 = Promise.reject(new Error("Error happened!"));
const P2 = 5;
const P3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("18.5.");
}, 100);
});
const promises = [P1, P2, P3];
try {
const result = await Promise.allSettled(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //Array [
//Object { status: "rejected", reason: Error: Error happened! },
//Object { status: "fulfilled", value: 5 },
//Object { status: "fulfilled", value: "18.5." }]
正如我们在上面的示例中看到的,方法也可以接收非承诺值。
如果传递一个空的可迭代对象,Promise.allSettled() 将返回一个已解析的 Promise 对象作为空数组。
async function f() {
try {
const result = await Promise.allSettled([]);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //Array []
Promise.any()
Promise.any() 是最新的 Promise 组合器,目前处于TC39 流程的第 3 阶段。它需要一个可迭代对象,一旦其中一个 Promise 得到满足,就会返回该 Promise。
async function f() {
const P1 = Promise.resolve(18);
const P2 = Promise.resolve(5);
const P3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("18.5.");
}, 100);
});
const promises = [P1, P2, P3];
try {
const result = await Promise.any(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //18
此方法与 Promise.all() 之间的区别在于 Promise.all() 返回履行值数组,而 Promise.any() 仅返回第一个履行值。Promise.race() 与 Promise.any() 不同,因为 Promise.race() 返回第一个固定值(已实现或已拒绝),而 Promise.any() 会忽略被拒绝的 Promise,直到第一个 Promise 已实现。
async function f() {
const P1 = Promise.reject(new Error("Error happened!"));
const P2 = Promise.resolve(5);
const P3 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("18.5.");
}, 100);
});
const promises = [P1, P2, P3];
try {
const result = await Promise.any(promises);
console.log(result);
} catch (err) {
console.log(err);
}
}
f(); //5
如果传递了一个空的可迭代对象,该方法将返回一个已经解决的承诺。
如果所有给定的 Promise 都被拒绝,该方法会异步拒绝 AggregateError ,这是一个新的 Error 子类,它将各个错误组合在一起。
Promise.any() 仍处于实验阶段,浏览器尚未完全支持。