Promise.all返回另一个承诺

时间:2020-07-23 14:45:41

标签: javascript

我在Javascript中具有以下功能:

// fetches the username based on the user ID

const fetchUsername = async (userId) => {
    const response = await axios({ ... });
    return {
        userId,
        username: response.data.username
    }
};

// fetches the online status based on the user ID

const fetchOnline = async (userId) => {
    const response = await axios({ ... });
    return {
        userId,
        online: response.data.online
    }
};

const fetchUsers = (userIds) => {
    const promises = [];
    userIds.forEach(userID => {
        return new Promise(async (resolve, reject) => {
            const usernameObject = await fetchUsername(userId);
            const onlineObject = await fetchOnline(userId);
            resolve({ ...usernameObject, ...onlineObject });
        })
    })
    Promise.all([promises]).then(response => console.log(response));
};

我对这段代码有2个问题:

  1. Promise.all()。then()中的响应是另一个承诺。它不是一个包含用户名和在线状态的对象的数组,而是一个承诺(例如:{"_40": 0, "_55": null, "_65": 0, "_72": null})。

  2. 在新的Promise中使用async / await是反模式,但是我不知道如何将2个promise的结果组合到1个对象上。

编辑:

我只能接受一个答案,但是Gabriel Donadel Dall'Agnol的答案帮助我解决了问题1,而Klaycon的答案帮助了我解决了问题2。

非常感谢大家!

2 个答案:

答案 0 :(得分:3)

您只是错过了填充promises数组

const fetchUsers = (userIds) => {
const promises = userIds.map(userID => {
    return new Promise(async (resolve, reject) => {
        const usernameObject = await fetchUsername(userId);
        const onlineObject = await fetchOnline(userId);
        resolve({ ...usernameObject, ...onlineObject });
    })
})
Promise.all(promises).then(response => console.log(response));
};

答案 1 :(得分:3)

除了有关填充promises数组而不将其包装在另一个数组[promises]中的其他答案和注释之外:

在新的Promise中使用async / await是反模式,但是我不知道如何将2个promise的结果组合到1个对象上。

这是Array#map使用异步回调的便捷用例。如果将回调标记为异步,它将自动返回一个Promise,并将使用返回值进行解析。所以你可以这样写:

const promises = userIds.map(async userID => {
    const usernameObject = await fetchUsername(userId);
    const onlineObject = await fetchOnline(userId);
    return { ...usernameObject, ...onlineObject };
});

Promise.all(promises).then(response => console.log(response));