javascript - 我的 Promise.all() 实现有什么问题?
问题描述
我正在尝试编写我的Promise.all()
函数。它应该重复本机Promise.all()
方法的功能。
如果数组中只有 Promise,则代码可以正常工作,如果数组包含 Promise 以外的内容,则可能会出现问题。
下面是一个执行示例:
const p1 = Promise.resolve(3);
const p2 = 1337;
const p3 = new Promise((resolve, reject) => {
setTimeout(resolve, 10000, 'foo');
});
promiseAll([p1, p3, p3]).then(values => console.log(values)); // [3, 1337, "foo"]
这是我的代码:
const promiseAll = promises => new Promise((resolve, reject) => {
if (promises.length === 0) { resolve([]); }
const results = [];
let resolved = 0;
promises.forEach(promise => {
if (!(promise instanceof Promise)) {
Promise.resolve(promise).then(data => results.push(data));
}
promise.then(result => {
results.push(result);
resolved += 1;
if (resolved === promises.length) {
resolve(results);
}
}, error => reject(error));
});
});
问题是什么?
解决方案
您的实施存在两个主要问题:
在
forEach()
方法内部,您有一个检查:promise instanceof Promise
. 如果这个检查是假的,你打电话Promise.resolve()
BUT 然后你也打电话promise.then(...)
; 您可能打算在块then()
内调用方法else
Promise.all()
维持秩序 - 你的实施没有。results
这是因为您只需按照解决承诺的顺序将承诺结果推送到数组中
您可以如下所示更改您的实现以解决上述问题:
const promiseAll = promises => {
return new Promise((resolve, reject) => {
if (promises.length === 0) {
resolve([]);
return;
}
const results = [];
let resolved = 0;
function collectResult(result, index) {
results[index] = result;
resolved += 1;
if (resolved === promises.length) {
resolve(results);
}
}
promises.forEach((value, index) => {
if (
typeof value === 'object' &&
'then' in value &&
typeof value.then === 'function'
) {
value.then(res => collectResult(res, index)).catch(reject);
} else {
Promise.resolve(value).then(res => collectResult(res, index));
}
});
});
};
推荐阅读
- c# - 在 WinForm C# 中单击按钮时更改表格单元格颜色
- json - Marklogic 9 在 json 文档上提取文档数据
- php - Apache2 PHP docker容器,如何将错误记录为stderr并将信息作为stdout记录到容器日志?
- python - 如何在 tkinter 中平滑椭圆周围的边缘?
- python - 如何使用matplotlib在python中绘制图形时显示值
- typescript - 描述 typescript 函数,它使用数组中的键返回修改后的对象
- php - 在自定义页面中制作自定义 woocommerce 帖子以使用 ajax
- r - 如何使用评估在 R 中捕获错误消息
- html - 在 Netlify 上部署后,Roboto 字体在 Safari 或移动浏览器中不起作用
- python - setdefault 附加到每个键