Q:

Javascript: Add timeout after every request in Promise.all Map function

For the following function, I have to add a timeout after every GET request in array ajaxUrls. All the XHR GET request are in array ajaxUrls.
function getAllSearchResultProfiles(searchAjaxUrl) {
  var ajaxUrls = [];
  for (var i = 0; i < numResults; i += resultsPerPage) {
    ajaxUrls.push(searchAjaxUrl + "&start=" + i);
  }
  return Promise.all(ajaxUrls.map(getSearchResultsForOnePage))
    .then(function(responses) {
      return responses.map(function(response) {
        if (response.meta.total === 0) {
          return [];
        }
        return response.result.searchResults.map(function(searchResult) {
          return (searchResult);
        });
      });
    })
    .then(function(searchProfiles) {
      return [].concat.apply([], searchProfiles);
    })
    .catch(function(responses) {
      console.error('error ', responses);
    });
}

function getSearchResultsForOnePage(url) {
  return fetch(url, {
      credentials: 'include'
    })
    .then(function(response) {
      return response.json();
    });
}

I want a certain timeout or delay after every GET request. I am facing difficulty in where exactly to add the timeout.

A:

If you want to make requests in serial, you shouldn't use Promise.all, which initializes everything in parallel - better to use a reduce that awaits the previous iteration's resolution and awaits a promise-timeout. For example:
async function getAllSearchResultProfiles(searchAjaxUrl) {
  const ajaxUrls = [];
  for (let i = 0; i < numResults; i += resultsPerPage) {
    ajaxUrls.push(searchAjaxUrl + "&start=" + i);
  }
  const responses = await ajaxUrls.reduce(async (lastPromise, url) => {
    const accum = await lastPromise;
    await new Promise(resolve => setTimeout(resolve, 1000));
    const response = await getSearchResultsForOnePage(url);
    return [...accum, response];
  }, Promise.resolve([]));

  // do stuff with responses
  const searchProfiles = responses.map(response => (
    response.meta.total === 0
    ? []
    : response.result.searchResults
  ));
  return [].concat(...searchProfiles);
}

Note that only asynchronous operations should be passed from one .then to another; synchronous code should not be chained with .then, just use variables and write the code out as normal.

