Возвращаемое значение вне всех циклов

#javascript

#javascript

Вопрос:

Как вернуть мой serviceName массив вне всех циклов?

Вот мой код:

 data.forEach(async (e) => {
  let serviceName = [];

  const orders = await this.getOrders(e.id);

  orders.forEach(async (a) => {
    serviceName.push(a.serviceName);
  });
});

return serviceName; //NOT WORK
  

спасибо за любую помощь

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

1. Переместите объявление выше data.forEach(async e => { . Хотя, если вы выполняете асинхронный цикл, вам, вероятно, понадобится for..of с await помощью inside или Promise.all в зависимости от того, нужно ли вам делать это последовательно или если это нормально, чтобы это происходило параллельно

2. можете ли вы показать пример?

Ответ №1:

Поскольку вы имеете дело с асинхронными функциями, я предлагаю вам использовать .map() вместо .forEach() :

 let = []; // declared outside the loop

const serviceNames = await Promise.all(
  data.map(async (e) => {
    const orders = await this.getOrders(e.id);

    return orders.map((a) => a.serviceName); // return the array of serviceName
  })
);

return serviceNames.reduce((acc, curr) => acc.concat(curr), []); // or use flatMap if you are running a newer JS version
  

Ответ №2:

Используйте for..of loop для перебора асинхронных функций и возврата результатов.

 (async () => {
    let serviceName = [];
    for (const item of data) {
        const orders = await this.getOrders(item.id);

        for (const order of orders) {
            serviceName.push(order.serviceName);
        }
    }
    
    return serviceName;
})();
  

Для параллельной версии —

Напишите функцию, которая принимает массив обещаний, которые не будут быстро завершаться сбоем из-за Promise.all's поведения, отфильтруйте разрешенные обещания и сопоставьте имена служб в новый массив.

 (async () => {
    const whenAll = (promises) => {
        const reflect = (promise) => {
            return promise.then((data) => ({
                status: 'Resolved',
                data
            }))
            .catch((err) => ({
                status: 'Rejected',
                error: err
            }));
        };

        return Promise.all(promises.map(reflect));
    };

    const promiseArr = data.map((item) => this.getOrders(item.id));
    const promiseResult = (await whenAll(promiseArr)).filter((res) => res.status === 'Resolved');
    const serviceName = promiseResult.map(({ data }} => data.serviceName);
    return serviceName;
})();
  

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

1. К вашему сведению: это приведет к выполнению одного элемента за другим

2. @MauriceNino ОП не указал, хочет ли он его параллельно

3. Вот почему я поставил там «К вашему сведению» 🙂 Это просто подсказка для всех, кто его использует, а не проблема с вашим кодом