Правильное дублирование объекта JS при создании нескольких запросов GET (с Ax ios) - PullRequest
0 голосов
/ 09 июля 2020

Ниже приведен фрагмент кода, который выполняет поиск в HackerNews api ключевого слова 'java' путем выполнения нескольких запросов на получение первых N страниц данных

В идеале он должен получить первые 3 страницы набора данных:

https://hn.algolia.com/api/v1/search_by_date?query=java&page=0
https://hn.algolia.com/api/v1/search_by_date?query=java&page=1
https://hn.algolia.com/api/v1/search_by_date?query=java&page=2

Вот код, который также доступен как CodePen

// Fetch all HackerNews posts with the search string 'java'
const url = 'https://hn.algolia.com/api/v1/search_by_date';

const config = {
  headers: { 'Content-Type': 'application/json', 'Accept': 'application/json' },
  params: { query: 'java', page: null }
};

const numPagesToFetch = 3;

// Build a series of requests, one for each page
let requests = [];
for (var i = 0; i < numPagesToFetch; i++) {
  
  // Duplicate the `config` object for each request
  let requestCfg = Object.assign({}, config);

  // The only `param` changing for each request is `?page=`
  // HN API starts numbering from page 0
  requestCfg.params.page = i;

  console.log(`Generating request for page ${requestCfg.params.page}`);
  requests.push(axios.get(url, requestCfg));
}

// Wait on all requests to complete in parallel, then handle the output
Promise.all(requests).
  then((responses) => {
    // Should be equal to numPagesToFetch (3)
    console.log(`Number of responses: ${responses.length}`);

    for(var i = 0; i < responses.length; i++) {
      // Print out some info about each response
      const firstId = responses[i].data.hits[0].story_id;
      const requestUrl = responses[i].request.responseURL;
      console.log(`Dataset Response from ${requestUrl} starts with id ${firstId}`);
    }
  }).
  catch(error => {
    console.log('There was an error');
  })

Когда я запускаю это, кажется, что он получает ту же страницу ( последняя страница) несколько раз

https://hn.algolia.com/api/v1/search_by_date?query=java&page=2
https://hn.algolia.com/api/v1/search_by_date?query=java&page=2
https://hn.algolia.com/api/v1/search_by_date?query=java&page=2

Мне кажется, это как-то связано с тем, как JS или ax ios обрабатывает ссылки на переменные. Когда я создаю каждый запрос и увеличиваю page, он влияет на все остальные запросы, построенные с той же переменной. Я даже постарался «продублировать» объект config, но это не помогает.

Есть идеи, почему он делает один и тот же запрос 3 раза?

Спасибо!

1 Ответ

1 голос
/ 09 июля 2020

Это потому, что вы не клонируете его глубоко, вы только клонируете объект root, но внутренние объекты по-прежнему указывают на свой исходный объект ... вы можете либо использовать https://www.npmjs.com/package/clone-deep, либо использовать это небольшой трюк с преобразованием его в строку и последующим синтаксическим анализом как объекта:

let requestCfg = JSON.parse(JSON.stringify(config));
...