В ожидании GET-запросов в цикле For - PullRequest
0 голосов
/ 18 мая 2018

Я пытаюсь сделать несколько запросов GET к веб-серверу, используя Axios и Node.Я использую асинхронную функцию для получения массива значений, для запроса уникальных URL-адресов на одном и том же веб-сайте.

Каждый раз, когда выполняется цикл, я отправляю ответ в массив, называемый «результаты».

Когда цикл завершается, асинхронная функция завершается, и я добавляю функцию .then, передавая ей возвращаемое значение.Затем я записываю это на экран.

Моя проблема в том, что оператор return срабатывает перед выполнением моих запросов.Другими словами, записывается пустой массив, и затем все запросы завершаются.

Как я могу вернуть результаты цикла for только в асинхронную функцию послезапросы GET завершены, а массив заполнен значениями?

Спасибо за помощь, вот код:

const axios = require("axios");

var loop = [about,home,products,thanks]
var i;

const results = [];

const test = async () => {
    for(i = 0; i < loop.length; i++) {
        axios.get(`https://examplewebsite.com/${loop[i]}`)
            .then((response,body) => {
                results.push(response);
            })
            .catch((error) => {
                console.log(error)
            });
    };
    // THIS IS NOT CORRECT, IT CAUSES MY RESULTS TO BE RETURNED IMMEDIATELY
    return results;
}

test().then((results) => {
    console.log(results); // Currently outputs --> [ ]  
});

1 Ответ

0 голосов
/ 18 мая 2018

Моя проблема в том, что оператор return срабатывает до выполнения моих запросов.Другими словами, регистрируется пустой массив, а затем все запросы завершаются.

Вы не сохраняете ссылку на каждую из цепочек обещаний, созданных с помощью axios.get(), поэтому выне могу их ждать.

После инициализации приведенный выше код выполняется следующим образом:

  1. Вызов test()
  2. Повторяйте и создавайте каждый запрос с помощью axios.get()
  3. Возврат results
  4. .then((results) => console.log(results) вызывается, а results печатаются как []
  5. Обрабатывает проверки, если ожидается какая-либо асинхронная работа - Ничего не ожидается
  6. Процесс завершается

Для того, чтобы хотя бы один из ваших запросов был обработан, потребовался бы по крайней мере следующий ход цикла событий.Однако, поскольку ваш код выполняется за один оборот четного цикла, он выполняет весь код, который вы написали, кроме обработчика ответа, присоединенного к axios.get().Если вы хотите получить более подробное объяснение того, что происходит на каждом ходу цикла событий и как все это работает, вы можете прочитать об этом подробнее здесь .

Вам необходимо вернуть ссылкуна каждое обещание, возвращаемое с axios.get().Вместо того, чтобы хранить их ответы в Массиве, храните Обещания от axios.get().Даже если вы используете синтаксис async/await, вам все равно нужно использовать Promise.all(), чтобы ожидать более одного Обещания одновременно.Promise.all() можно использовать для ожидания всех цепочек обещаний запросов, хранящихся в вашем массиве.

Выше можно написать более кратко, используя Array#map для перебора списка элементов и возврата результатов массива обещаний.,

const axios = require("axios");

const baseURL = 'http://examplewebsite.com/'        
const requestList = items => Promise.all(
  items.map(key => (
    axios.get(`${baseUrl}${key}`)
      .catch(err => console.error(err))
  )
)

requestList(['about', 'home', 'products', 'thanks'])
  .then(results => console.log(result))
  .catch(err => console.error(err))
...