1

所以我有一个需要多次调用的异步函数。当然,我想使用 Promise.all

const promises = [];
ids.forEach((id) => {
  stockoutPromises.push(
    asyncFunc(id),
  });
});
results[] = Promise.all(promises);

好的,没问题,但我怎么知道哪个 id 与哪个结果?当然我可以再次遍历这两个数组,但是还有另一种方法吗?有没有一种方法可以创建一个承诺,当解决后会给我一个包含 id 和 result 的对象?

谢谢!

4

3 回答 3

3

将 a 链接.then到 of 的调用上,asyncFunc以便生成的项不仅是asyncFunc结果,而且是结果和对象中的 ID:

ids.forEach((id) => {
  stockoutPromises.push(
    asyncFunc(id).then(result => ({ id, result }))
  );
});

但最好使用.map而不是.push循环使用:

const results = await Promise.all(
  ids.map(id =>
    asyncFunc(id).then(result => ({ id, result }))
  )
);
const firstItem = results[0];
console.log(firstItem.result, firstItem.id);
于 2020-12-03T03:58:33.247 回答
0

不要使用forEach,而是使用map

const promises = ids.map((id) => {
    return asyncFunc(id)
});
const results = await Promise.all(promises);

map将根据提供的函数返回的内容返回一个新的对象数组。在您的情况下,您正在调用 an asyncFunc,我假设它本身会返回一个 Promise。因此,您可以直接返回 map 的结果,而无需推送到新的 Promise数组

另外,请确保“等待”对Promise.all;的调用

您可以在这个 jsfiddle中查看它,它只返回一个将数组asyncFunc中的 id 翻倍的承诺。ids

于 2020-12-03T04:49:53.980 回答
0

的结果Promise.all将按照它们最初的顺序(在承诺数组中)。因此,您只需使用索引即可轻松重新关联:

// zip takes an array of keys, and an array of values, and creates an object:
const zip = (a, b) => Object.fromEntries(a.map((k, i) => [k, b[i]]));

// first id will resolve last, second will resolve next, etc.
const ids = [0, 1, 2, 3, 4];
const promises = ids.map((i) => new Promise((resolve) => {
    setTimeout(() => resolve(i), 700 - (100 * i));
}));

// but we still get the correct item in each spot, because of how
// Promise.all works:
(async () => {
    console.log(zip(ids, await Promise.all(promises)));
})()

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

返回值将按照 Promises 传递的顺序排列,无论完成顺序如何。

于 2020-12-03T04:07:52.330 回答