#javascript #fetch
#javascript #выборка
Вопрос:
Я работаю над приложением, которое возвращает список идентификаторов из первого запроса на выборку. После получения идентификаторов я должен перебрать идентификаторы и получить подробную информацию о каждом элементе, а затем отобразить его на экране.
fetch(TOP_STORIES)
.then(function(response){
return response.json()
}).then(function(storyIds){
// storyIds is [22,33,44,55,66,77,88,99,123,213,342,45456,778,888]
// is this the best way to fetch all the details of the story
storyIds.forEach(function(storyId){
let storyDetailsURL = `https://someurl/v0/item/${storyId}.json?print=pretty`
fetch(storyDetailsURL)
.then((response) => response.json())
.then((story) => {
displayStory(story)
})
})
})
Мой вопрос в том, является ли цикл лучшим способом получения результатов?
ОБНОВЛЕНИЕ: Обещание.все это вызывает у меня проблемы:
ОБНОВЛЕНИЕ: Использование Async и Await
async function fetchTopHeadlinesAsyncAwait() {
let response = await fetch(TOP_STORIES)
let storyIds = await response.json()
for(let storyId of storyIds) {
console.log(storyId)
let storyDetailsURL = `someurl/er/tg/${storyId}.json?print=pretty`
let response = await fetch(storyDetailsURL)
let story = await response.json()
displayStory(story)
}
}
Комментарии:
1. мне это не нравится, потому что это забивает сервер всеми запросами сразу. Обычно было бы лучше запрашивать их по одному за раз. Для этого я определяю, индексирую и создаю функцию next(), которая извлекает отдельный элемент по идентификатору. next() проверяет индекс, чтобы увидеть, является ли он последним. Если нет, увеличьте индекс и вызовите next(), в противном случае остановитесь и сделайте что-нибудь еще. Не забудьте вызвать next() вручную один раз в нижней части содержащего контекста…
2. кстати, если вы переключитесь на использование кода в стиле async / await вместо Promise.then , он будет хорошо очищен и станет более удобным в использовании. Обещания все же хороши. Я бы сделал что-то другое, кроме получения деталей истории только при необходимости.
3. Можете ли вы попробовать просто удалить строку функции json ()?
4. ах, асинхронность / ожидание. так намного чище.
5. @johndoe я обновил свой ответ, поэтому json теперь должен работать с массивом обещаний. .json() не сработал, потому что он был вызван для массива ответов.
Ответ №1:
Вы можете использовать функциональность Promise.all для извлечения списка асинхронных действий. Они будут завершены, когда все будут успешными.
Вот пример вашего кода с Promise all, дайте мне знать, как это работает 🙂
const fetchStories = () => {
let response = await fetch(TOP_STORIES);
let storyIds = await response.json();
let urls = [];
storyIds.forEach(function(storyId) {
urls.push(`https://someurl/v0/item/${storyId}.json?print=pretty`);
});
Promise.all(
urls.map(url =>
fetch(url)
.then(response => response.json())
.catch(err => console.error(err))
)
).then(stories => stories.forEach(story => displayStory(story)));
}
Комментарии:
1. Спасибо! В вашем коде, если одно из обещаний не выполняется, прерывает ли оно все или по-прежнему получает те, которые являются успешными.
2. Привет, если одно обещание не выполняется, все они будут выполнены с ошибкой, используя этот метод.
3. Спасибо! Я не думаю, что хочу этого, поскольку я извлекаю новостные статьи, и если одна из них завершается неудачей, я не хочу, чтобы все завершилось неудачей.
4. вместо этого используйте Promise.any в цикле