javascript - 如何在 Javascript 中为 Promise.all 编写 Polyfill 时处理 setTimeout 情况
问题描述
我正在尝试为 Promise.all 编写一个 polyfill,当我在没有 setTimeout 的情况下通过 Promise 时它工作正常,但是使用 setTimeout,我没有得到正确的结果,因为它在计时器到期之前解析并返回了 Promise。
如何处理这种情况以在以下函数中工作,与实际 Promise.all 的工作方式相同。
下面是我的代码片段和codesandbox的链接
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("success 1"), 2000);
});
const promise2 = new Promise((resolve, reject) => {
resolve("success 2");
});
const promise3 = new Promise((resolve, reject) => {
resolve("success 3");
});
function resolveAll(promiseArr) {
let arr = [];
return new Promise((resolve, reject) => {
promiseArr.map((each_promise, index) => {
return each_promise
.then((res) => {
arr[index] = res;
if (index === promiseArr.length - 1) {
resolve(arr);
}
})
.catch((err) => {
reject(err);
});
});
});
}
resolveAll([promise1, promise2, promise3])
.then((res) => {
console.log(res, "result");
})
.catch((err) => console.log(err, "error"));
实际结果:[undefined, "success 2", "success 3"]
预期结果:[“成功 1”、“成功 2”、“成功 3”]
解决方案
你的问题是
if (index === promiseArr.length - 1) {
resolve(arr);
}
只是检查最后一个承诺是否已解决,但在您的场景中,第一个承诺是由于 setTimeout 而得到解决的最后一个承诺。
一种解决方案是记录有多少承诺已经解决,例如
const promise1 = new Promise((resolve, reject) => {
setTimeout(() => resolve("success 1"), 2000);
});
const promise2 = new Promise((resolve, reject) => {
resolve("success 2");
});
const promise3 = new Promise((resolve, reject) => {
resolve("success 3");
});
function resolveAll(promiseArr) {
let arr = [],
errorMsg = [],
resolvedPromiseCount = 0;
return new Promise((resolve, reject) => {
promiseArr.map((each_promise, index) => {
return each_promise.then((res) => {
console.log(res)
arr[index] = res;
resolvedPromiseCount++;
if (resolvedPromiseCount === promiseArr.length) {
resolve(arr);
}
})
.catch((err) => {
resolvedPromiseCount++;
errorMsg.push(err);
});
});
});
}
resolveAll([promise1, promise2, promise3]).then((res) => {
console.log(res, "result");
})
.catch((err) => console.log(err, "error"));
推荐阅读
- xamarin - 在 Xamarin Forms Application 中上传文档
- java - 如何在服务器上通过 Java 运行 Powershell 命令
- bitbucket - 使用 rsync 部署 Bitbucket 管道 - 主机密钥验证失败
- c# - 如何结合将分数转换为双精度数的方法和将数字提高到另一个数字的幂的方法?
- javascript - Intersection Observer 不适用于 jQuery UI 对话框
- reactjs - 排序后组件请求数据
- javascript - 使用 Angular 7 将图像文件与其他表单数据一起提交到服务器
- amazon-dynamodb - 如何在 BatchGetItem 中使用过滤器
- c++ - 1000 个共享指针占用多少内存?
- python - 当我为每个任务有不同数量的数据样本时,是否可以制作多输入和多输出 DNN 模型