Выполнение запроса на выборку в цикле

#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 в цикле