Пусть начальным значением аккумулятора является Обещание, которое разрешается в пустой массив, затем await
аккумулятор на каждой итерации (чтобы все предыдущие итерации разрешались до выполнения текущей итерации)
.then(responses=> {
return responses.reduce(async (accPromiseFromLastIter, next) => {
const arr = await accPromiseFromLastIter;
arr.push(await next.json());
return arr;
}, Promise.resolve([]))
})
(Тем не менее, ваш оригинальный код намного понятнее, я бы предпочел его * версии .reduce
)
Live демо:
const makeProm = num => Promise.resolve(num * 2);
const result = [1, 2, 3].reduce(async(accPromiseFromLastIter, next) => {
const arr = await accPromiseFromLastIter;
arr.push(await makeProm(next));
return arr;
}, Promise.resolve([]));
result.then(console.log);
Если у вас нет для получения всех данных в последовательном порядке, рассмотрите возможность использования Promise.all
для параллельного вызова .json()
каждого Promise, поэтомучто результат будет получен быстрее:
return Promise.all(queries)
.then(responses => Promise.all(responses.map(response => response.json())));
Если запросы являются массивом Response
s, которые были только что сгенерированы из fetch
, было бы еще лучше связать вызов .json()
свместо этого исходный fetch
вызов, например:
const urls = [ ... ];
const results = await Promise.all(
urls.map(url => fetch(url).then(res => res.json()))
);
Таким образом, вы можете потреблять ответы немедленно , когда они возвращаются, вместо того, чтобы ждать все ответов, которые нужно вернуть перед началом обработки первого.