Возвращает ответ на 2 «синхронных» вложенных запроса (Express, Mongoose)

#javascript #arrays #express #mongoose

#javascript #массивы #экспресс #mongoose

Вопрос:

Я хочу вернуть массив элементов, подобных этому:

 ApiResponse = [
   {_id: 1,
   name: Mike,
   transactions: 5},
   
    {_id: 2,
    name: Jhon,
    Transactions: 10}
]
 

Первые данные «Пользователи» поступают из запроса к схеме «Пользователи», но номер «Транзакции» поступает из запроса другой схемы «Транзакции»

Я попробовал следующую логику:

  1. Получить всех пользователей, использующих:
  2. Повторите массив «respUsers» с помощью функции map:
  3. для каждого «пользователя», который я получил, я хочу запросить все транзакции, связанные с:
  4. тогда я просто хочу, чтобы «длина» массива была такой:
  5. и чтобы закончить, я хочу, чтобы функция map возвращала массив объектов, таких как:

Чтобы закончить со следующим полным кодом для контроллера api:

 exports.list = async (req, res) => {
    //Find all users
    const respUsers = await User.find().exec();

    const responseArray = respUsers.map(async (user) => {
        let transactions = await Transactions.find({
            doctorOwner: user._id,
        }).exec();
        let transactionsLength = await transactions.length;

        return {
            _id: user._id,
            name: user.name,
            transactions: transactionsLength 
        };
    });

    console.log(responseArray);

    res.json(responseArray);
};
 

но я получил 3 пустых массива [], [],[]

и если я утешу.войдите в систему на стороне сервера, которую я получил:

 [ Promise { <pending> }, Promise { <pending> }, Promise { <pending> } ]
 

Как я могу это сделать?

Комментарии:

1. попробуйте что-то вроде этого, пусть responseArray = await respUsers.map(async (promise, user) => { await promise; //выполняйте свою логику здесь }.Promise.resolve());

2. Извините, не работает: (

Ответ №1:

Этот код работает. Это было примерно Promise.all() . Он создает обещание, которое разрешается, когда все остальные обещания внутри разрешены.

 // Emulates User.find().exec()
async function getUsers() {
    return Promise.resolve([
        {
            _id: "id1",
            name: "John",
        },
        {
            _id: "id2",
            name: "Johny",
        },
        {
            _id: "id3",
            name: "Jonas",
        },
    ]);
}
// Emulates Transactions.find({} doctorOwner: user._id )
async function getTransactions() {
    const arr = [];
    for (let i = 0; i < Math.round(Math.random() * 100); i  ) {
        arr.push("transaction");
    }
    return Promise.resolve(arr);
}

const superFunc = async (req, res) => {
    // Find all users
    let respUsers = await getUsers();

    const responseArray = Promise.all(
        respUsers.map(async (user) => {
            let transactions = await getTransactions();
            let transactionsLength = transactions.length;

            const toReturn = {
                _id: user._id,
                name: user.name,
                transactions: transactionsLength,
            };
            return toReturn;
        })
    );

    console.log(await responseArray);
};

superFunc(); 
 .as-console-wrapper {
  max-height: 100% !important;
  top: 0;
} 

Комментарии:

1. Я добавляю ожидание, как вы показываете, и все равно получаю [Обещание {<ожидание> }, Обещание { <ожидание> }, обещание { <ожидание> } ]

2. Странно. Подумав об этом, кажется, что функция map выполнила свою работу правильно, но она возвращает обещания… Я внес изменения. Каков результат сейчас?

3. Я вношу все изменения в код, которые вы мне предлагаете, и я все еще получаю [Promise { <ожидание> }, Promise { <ожидание> }, Promise { <ожидание> } ]

4. Я отладил его и отредактировал, вот код! Конечно, вам следует удалить и заменить функции эмуляции, они здесь только для демонстрации фрагментом кода SO.