2

考虑一堆承诺 -result1, result2, results3等等。

我等待等待Promise.all,然后处理已解决的对象。不再需要承诺。

我可以像这样使用解构赋值:-

[result1, result2, result3] = await Promise.all([result1, result2, result3]);

但是那里有重复([result1,result2...] 使用了两次)并且它已经成熟,因为有大量的 promises 会出错。

有没有更好的办法?

4

1 回答 1

2

您可以拥有一个使用对象而不是数组的实用程序函数,类似于以下内容:

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;
}

然后它会是这样的:

const {a, b, c} = await allKeyed({
    a: promise1,
    b: promise2,
    c: promise3,
});

...但使用有意义的名称而不是a,bc. :-)

现场示例:

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));

在问题中,您在Promise.all为承诺(用于输入Promise.all)和它们的履行值(在解构中)使用相同的名称之前将承诺分配给变量,如下所示:

// ...assign promises to `resultX`, then:
({result1, result2, result3} = await allKeyed({result1, result2, result3}));

我在那里按顺序排列它们,但这也可以:

// ...assign promises to `resultX`, then:
({result3, result1, result2} = await allKeyed({result1, result2, result3}));

现场示例:

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));

于 2021-04-03T12:10:02.167 回答