在 Javascript 中为 Promise.all 编写 Polyfill 时如何处理 setTimeout 情况
How to handle setTimeout case while writing Polyfill for Promise.all in Javascript
我正在尝试为 Promise.all 编写一个 polyfill,当我在没有 setTimeout 的情况下通过承诺时它工作正常,但是使用 setTimeout,我没有得到正确的结果,因为它解析并且 returns计时器到期前的承诺。
如何处理这种情况以在下面的函数中工作,与实际 Promise.all 工作方式相同。
下面是我的代码片段和 link 到 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"));
实际结果:[未定义,“成功 2”,“成功 3”]
预期结果:[“成功1”、“成功2”、“成功3”]
你的问题是
if (index === promiseArr.length - 1) {
resolve(arr);
}
只是检查最后一个 promise 是否已解决,但在您的场景中,第一个 promise 是最后一个由于 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"));
我正在尝试为 Promise.all 编写一个 polyfill,当我在没有 setTimeout 的情况下通过承诺时它工作正常,但是使用 setTimeout,我没有得到正确的结果,因为它解析并且 returns计时器到期前的承诺。
如何处理这种情况以在下面的函数中工作,与实际 Promise.all 工作方式相同。
下面是我的代码片段和 link 到 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"));
实际结果:[未定义,“成功 2”,“成功 3”]
预期结果:[“成功1”、“成功2”、“成功3”]
你的问题是
if (index === promiseArr.length - 1) {
resolve(arr);
}
只是检查最后一个 promise 是否已解决,但在您的场景中,第一个 promise 是最后一个由于 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"));