Функция параллельного запуска NodeJS для извлечения данных из REST API

#node.js #api #rest

#node.js #API #rest

Вопрос:

Я работал с Node.js кодом, в котором я вызываю API. Я получаю разбитый на страницы ответ из 50 объектов одновременно. В параметре запроса я устанавливаю смещение как 0, 50, 100, чтобы продолжать извлекать больше данных. если в ответе содержится 50 объектов, я увеличиваю параметр запроса смещения. И как только данных меньше 50, я останавливаю вызов. Есть ли какой-либо способ разделить вызов, чтобы получить данные более быстрым способом? Предположим, я вызываю api?offset=0, api?offset= 50, api?offset= 100, api?offset= 150 параллельно, чтобы быстрее получать данные и собирать данные обо всех выполненных вызовах. Также, если данных нет, прекратите вызывать следующие значения смещения. ПРИМЕЧАНИЕ: я не знаю предела смещения.

Ответ №1:

Используйте рекурсивную функцию

Поскольку вы не знаете, каким будет предел смещения, лучше всего предположить, что для больших групп запросов, так что вы быстрее достигнете своего смещения.

Для асинхронных задач я люблю использовать async here . Вот пример :

 const async = require('async')

const offsets = [0, 50, 100, 150];
async.map(offsets, function (offset, callback) {
  
  // Do request here with 'offset'
  // And return response in the callback
  // Do not return an error, otherwise the main callback (of map function)
  // will be called immediately
  return callback (null, response);

}, function (error, results) {

  // results is an array containing all responses from all requests
  // iterate over results, if all contain a valid result, 
  // you can increase your offset group and perform this operation again

});
 

Конечно, вам нужно будет обернуть это в другую функцию, которая позволяет увеличивать offsetgroup , повторяя запросы до тех пор, пока вы получаете действительные результаты -> так называемая рекурсивная функция :

 const async = require('async')

function performGroupRequest (offsets, allResults, end) {
  
  async.map(offsets, function (offset, callback) {
  
    // Do request here with 'offset' and return response in the callback
    return callback (null, response);

  }, function (error, results) {
  
    // check results
    results.map(r => {
      if (hasItems(r)) {
        // valid result, add to allResults
        allResults.push(r);
      } else {
        // invalid result, let's end here
        return end(allResults);
      }
    });

    // all results are valid here, so call the function again, with increased offset
    performGroupRequest(offsets.map(o => o   200), allResults, end)

  });
}

function getAllItems () {
  return Promise((resolve, reject) => {
  
    performGroupRequest([0, 50, 100, 150], [], function(all) {
      return resolve(all);
    });
  
  });
}

// start the journey

getAllItems().then((allResults) => {
});
 

👆 Пожалуйста, обратите внимание: я полностью опустил обработку ошибок здесь по соображениям простоты.