简体   繁体   English

使用 await Promise.all 获取已解析对象的更简洁方法

[英]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 . ...但使用有意义的名称而不是abc :-) :-)

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM