我尝试实现Promise.all():
"use strict";
function all (...promises) {
const promise = new Promise((resolve, reject) => {
let counter = 0;
const values = [];
let rejected = false;
promises.forEach(
(promise, idx) => {
promise.then(val => {
counter++;
values[idx] = val;
if (counter === promises.length)
resolve(values);
},
() => {
if (!rejected) {
reject(new Error(`${promise} was rejected!`));
rejected = true;
}
}
);
}
);
});
return promise;
};发布于 2020-02-12 00:52:47
很好地使用const用于values,以及let用于可重新分配的值,如counter和rejected。
你测试过这段代码吗?我的假设是它没有发生,因为当我试过运行它时,我看到了以下错误:
错误promise.then不是一个函数
这是因为承诺是分散的:
函数all (...promises) {
如果没有spread操作符,只要promises中的每个条目都是承诺的,它就会像我所期望的那样运行。
我必须承认我和的另一项实施Promise.all()相比。与该函数相比,您的函数跟踪rejected,而另一个函数只在承诺被拒绝时调用reject。
我注意到的另一件事是,变量名promise被重用-- all()返回外部承诺以及对promises.forEach()的回调。明智的做法是使用不同的名称来提高可读性。实际上,不需要赋值外部承诺--它可以简单地返回而不被分配给一个变量,因为它在实例化后不会被修改。
需要考虑的另一个方面是,Promise.all()可以接受承诺,也可以不接受承诺--例如,MDN文档给出了如下示例:
const promise1 = Promise.resolve(3);
const promise2 = 42; // <- not really a promise
const promise3 = new Promise(function(resolve, reject) {
setTimeout(resolve, 100, 'foo');
});
Promise.all([promise1, promise2, promise3]).then(function(values) {
console.log(values);
}).catch(error => {
console.log('error: ', error.message);
});
// expected output: Array [3, 42, "foo"]在使用代码时,它会抛出错误promise.then is not a function,因此在调用.then()之前检查每个项目是否是一个承诺可能是明智的。
https://codereview.stackexchange.com/questions/235344
复制相似问题