Выполнение запроса Fetch в цикле - PullRequest
0 голосов
/ 14 марта 2019

Я работаю над приложением, которое возвращает список идентификаторов из первого запроса на выборку. После получения идентификаторов я должен пройтись по идентификаторам и получить подробную информацию о каждом элементе, а затем отобразить его на экране.

  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)
        })
      })

  })

Мой вопрос заключается в том, что лучший способ получить результаты - это цикл?

ОБНОВЛЕНИЕ: Promise.all дает мне проблемы:

enter image description here

ОБНОВЛЕНИЕ: использование 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)
  }
}

Ответы [ 2 ]

2 голосов
/ 14 марта 2019

Вы можете использовать функциональность 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)));
}
0 голосов
/ 14 марта 2019

Эта простая попытка / отлов делает ваш асинхронный код не нарушенным, если одна из историй выдает ошибку. В этом случае я отображаю сообщение об ошибке, используя вашу функцию displayStory, но делайте что хотите.

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`
    try {
      let response = await fetch(storyDetailsURL)
      let story = await response.json()
      displayStory(story)
    } catch (err) {
      displayStory('An error occurred while fetching this story.');
    }

  }
}
...