JavaScript 实现Promise.all()方法的Polyfill
任务是为javascript编写一个Promise.all的polyfill。
什么是Polyfill?
Polyfill是一段计算机代码,用于在尚不支持某个功能的浏览器中实现该功能。这可能是因为您使用的浏览器的旧版本,或者新版本的浏览器没有该功能。
什么是Promise.all()?
Promise.all()方法实际上是Promise对象的一个方法(Promise对象也是JavaScript中用于处理所有异步操作的对象),它接受一个承诺数组(可迭代对象)作为输入。它返回一个单一的Promise,当作为一个可迭代对象传递的所有承诺都已解决或可迭代对象不包含承诺时,该Promise解析。简单来说,如果传入的任何承诺被拒绝,Promise.all()方法将异步拒绝已经被拒绝的承诺的值,无论其他承诺是否已解决。
语法:
Promise.all( iterable )
参数: 此方法接受一个参数 iterable,它接受一个包含一些 Promise 对象或一般数组的数组。
返回值: 它遵循一些规则来返回一个单个 Promise:
- 如果传递的参数为空,它返回一个已经解析的 Promise。
- 如果传递的 iterable 中不包含 Promise,它返回一个以异步方式已解析的 Promise。
- 对于其他所有情况,它返回一个待定的 Promise。
Promise.all() 方法的实现和拒绝:
实现: 返回的 Promise 被实现,
- 如果传递的 iterable 为空,那么此方法会同步返回一个已经解决的 Promise。
- 如果所有传递的 Promise 都被实现,返回的 Promises 会异步实现。
- 在这种情况下,此特定方法的成功执行完全依赖于所有 Promise 的成功执行。
拒绝: 如果任何一个传递的 Promise 被拒绝,那么此方法会拒绝该 Promise 的值,无论其他的 Promise 是否已解决。
让我们看一些 JavaScript Promise.all() 方法的例子:
例子 1:
Javascript
const p1 = Promise.resolve(3);
const p2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("foo");
}, 100);
});
Promise.all([p1, p2]).then((values) => {
console.log(values);
});
输出:
[3, "foo"]
示例2:
Javascript
const prom1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Resolved First after 1 second");
}, 1000);
});
const prom2 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve("Resolved First after 2 seconds");
}, 2000);
});
const prom3 = 20;
try {
let result = Promise.all([prom1, prom2, prom3]);
result.then((data) => console.log(data));
} catch (error) {
console.log(error);
}
输出:
[
'Resolved First after 1 second',
'Resolved First after 2 seconds',
20
]
让我们为Promise.all实现polyfill
方法:
- 我们将创建一个 myall 函数,它将以一个promise数组作为输入。
- 在 myall 函数中,我们将执行以下操作:
1. 我们将声明一个名为 promise, a result that 的const变量,它将存储所有promise的结果, 以及一个名为 total that 的变量,用于记录已解决的promise数量。
2. 我们将创建一个新的promise,在promise内部遍历接收到的所有promise,每当一个输入promise解决时,我们将增加 total ,并将解决的值存储在 result 数组中与promise所在的相同索引位置。如果 total 等于输入数组的长度,则我们将使用 result 数组解决。如果promise以错误拒绝,则我们将直接以相同错误拒绝它。
Javascript
const prom1 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("gfg1")
}, 1000)
})
const prom2 = new Promise(function (resolve, reject) {
setTimeout(() => {
reject("error")
}, 2000)
})
const prom3 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("gfg2")
}, 3000)
})
const prom4 = new Promise(function (resolve, reject) {
setTimeout(() => {
resolve("gfg3")
}, 3000)
})
Promise.myall = function (values) {
const promise = new Promise(function (resolve, reject) {
let result = [];
let total = 0;
values.forEach((item, index) => {
Promise.resolve(item).then((res) => {
result[index] = res;
total++;
if (total === values.length)
resolve(result);
}).
catch((err) => {
reject(err);
})
})
})
return promise
}
Promise.myall([
prom1,
prom2,
prom3
])
.then((res) => {
console.log(res);
})
.catch((er) => {
console.log(er)
})
Promise.myall([
prom1,
prom3,
prom4
])
.then((res) => {
console.log(res);
})
.catch((er) => {
console.log(er)
})
输出:
"error"
["gfg1", "gfg2", "gfg3"]
解释: 在第一个案例中,由于prom3抛出了一个错误,所以Promise.all被拒绝并返回错误消息。
在第二个案例中,由于所有的promises都成功返回了某个值,所以Promise.all返回一个包含三个promises解析值的数组。