[英]Cleaner way of using await Promise.all to get resolved objects
Consider a bunch of promises - result1, result2, results3
etc.考虑一堆承诺
result1, result2, results3
等。
I wait to await Promise.all
and then work with the resolved objects.我等待等待
Promise.all
然后使用已解析的对象。 No further need for the promises.不再需要承诺。
I can use a destructuring assignment like so:-我可以像这样使用解构赋值:-
[result1, result2, result3] = await Promise.all([result1, result2, result3]);
But there is repetition there ([result1, result2...] used twice) and its ripe for mistakes with a large number of promises.但是那里有重复([result1,result2...] 使用了两次)并且它已经成熟,因为有大量的 promises 会出错。
Is there a better way?有没有更好的办法?
You could have a utility function that used an object instead of an array, something along these lines:您可以有一个实用程序 function 使用 object 而不是数组,类似于以下内容:
async function allKeyed(promises) {
// Get an array of [name, value] pairs for the object's properties
const entries = Object.entries(promises);
// Wait for any thenables/promises in the values to settle
const values = await Promise.all(entries.map(([_, value]) => value));
// Build an object from those result values; this works because the
// array from `Promise.all` is in the same order as the array of
// values we gave it above.
const result = Object.fromEntries(entries.map(([key], index) => {
return [key, values[index]];
}));
return result;
}
Then it would be something like:然后它会是这样的:
const {a, b, c} = await allKeyed({
a: promise1,
b: promise2,
c: promise3,
});
...but with meaningful names rather than a
, b
, and c
. ...但使用有意义的名称而不是
a
、 b
和c
。 :-) :-)
Live Example:现场示例:
async function allKeyed(promises) { // Get an array of [name, value] pairs for the object's properties const entries = Object.entries(promises); // Wait for any thenables/promises in the values to settle const values = await Promise.all(entries.map(([_, value]) => value)); // Build an object from those result values; this works because the // array from `Promise.all` is in the same order as the array of // values we gave it above. const result = Object.fromEntries(entries.map(([key], index) => { return [key, values[index]]; })); return result; } function fetchSomething(value) { return new Promise(resolve => { setTimeout(() => { console.log(`fulfilling with ${value}`); resolve(value); }, Math.floor(Math.random() * 1000)); }); } (async () => { const {a, b, c} = await allKeyed({ a: fetchSomething("ayy"), b: fetchSomething("bee"), c: fetchSomething("see"), }); console.log({a, b, c}); })().catch(error => console.error(error));
In the question you were assigning the promises to variables before Promise.all
using the same names for both the promises (to feed into Promise.all
) and their fulfillment values (in the destructuring), which would look like this:在问题中,您将承诺分配给
Promise.all
之前的变量,对承诺(用于输入Promise.all
)及其履行值(在解构中)使用相同的名称,如下所示:
// ...assign promises to `resultX`, then:
({result1, result2, result3} = await allKeyed({result1, result2, result3}));
I have them in order there, but this would work just as well:我在那里按顺序排列它们,但这也可以:
// ...assign promises to `resultX`, then:
({result3, result1, result2} = await allKeyed({result1, result2, result3}));
Live Example:现场示例:
async function allKeyed(promises) { // Get an array of [name, value] pairs for the object's properties const entries = Object.entries(promises); // Wait for any thenables/promises in the values to settle const values = await Promise.all(entries.map(([_, value]) => value)); // Build an object from those result values; this works because the // array from `Promise.all` is in the same order as the array of // values we gave it above. const result = Object.fromEntries(entries.map(([key], index) => { return [key, values[index]]; })); return result; } function fetchSomething(value) { return new Promise(resolve => { setTimeout(() => { console.log(`fulfilling with ${value}`); resolve(value); }, Math.floor(Math.random() * 1000)); }); } (async () => { let result1 = fetchSomething("one"); let result2 = fetchSomething("two"); let result3 = fetchSomething("three"); ({result3, result1, result2} = await allKeyed({result1, result2, result3})); console.log({result1, result2, result3}); })().catch(error => console.error(error));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.