Проблема с Nodejs, отвечающим целым массивом объектов. Просто отвечает первым элементом

#node.js #arrays #fetch

#node.js #массивы #выборка

Вопрос:

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

 export default (req, res) => {
  if (req.method === 'POST') {
      let hackerArr = [];
      // this fetch call gets an array of article numbers like [2334, 5435, 21889, etc..]
      fetch(req.body.url, {
          method:"GET",
          headers: {
              "Content-Type": "application/json"
          }
      })
      .then(response => response.json())
      // the for loop below takes the array of article numbers from above and makes a call 
      // for each article
      .then(data => {
          for (let i = 0; i < req.body.count; i  ) {
              fetch(`https://hacker-news.firebaseio.com/v0/item/${data[i]}.json`, {
                  method: "GET",
                  headers: {
                      "Content-Type": "application/json"
                  }
              })
              .then(response => response.json())
              .then(data => {
                  // here I push the JSON object thats returned into an array
                  hackerArr.push(data)
                  // for some reason, this console.log shows the completed array of objects
                  // although i would only expect to see 1 object in the array, then 2, etc.
                  console.log(hackerArr)
                  res.setHeader('Content-Type', 'application/json');
                  // this only returns the first element (as expected)
                  res.send(JSON.stringify({ response: hackerArr })) 
              })
              .catch(err => console.log(err))
              // if i put the res.send here, i get an empty array back
          }
          // if i put the res.send here, i get an empty array back as well
      })
      .catch(err => console.log(err))
  } else {
    res.setHeader('Content-Type', 'application/json');
    res.end(JSON.stringify({ response: 'Invalid Request Method' }))
  }
}
  

Когда я консолью.зарегистрируйте массив (хотя и внутри цикла for), он показывает весь массив со всеми 30 элементами. Однако, когда я отправляю ответ обратно, я получаю только один элемент. Если я перемещаю ответ за пределы цикла for, я получаю пустой массив в качестве ответа… Я озадачен проблемой.

Комментарии:

1. Cannot set headers after they are sent to the client означает, что это не единственная ваша функция, которая выполняет res.write или res.json или res.someResponFunction, поэтому: покажите весь ваш маршрут. Начните с app.get и покажите все вызовы промежуточного программного обеспечения, которые использует (а также какие из них являются неявными)

Ответ №1:

После некоторого серьезного рефакторинга и использования await я получил нужный мне результат

       let hackerArr = [];
      const response = await fetch(req.body.url);
      const data = await response.json();
      // console.log(data)
      for (let i = 0; i < req.body.count; i  ) {
          const articleResponse = await fetch(`https://hacker-news.firebaseio.com/v0/item/${data[i]}.json`);
          const articleData = await articleResponse.json();
          await hackerArr.push(articleData)
      }
      await hackerArr.length > 1 ? res.send(JSON.stringify({ response: hackerArr })) : null;
  

Комментарии:

1. Как вы используете await без асинхронности