#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. Вот почему я поставил там «К вашему сведению» 🙂 Это просто подсказка для всех, кто его использует, а не проблема с вашим кодом