function attemptConsumeNextQueueItem(tileRequests, results, rejectOnTileFail) {
  const tileRequest = tileRequests[0];
  const requestPromise = tileRequest.terrainProvider.requestTileGeometry(
    tileRequest.x,
    tileRequest.y,
    tileRequest.level,
  );

  if (!requestPromise) {
    // getting back undefined instead of a promise indicates we should retry a bit later
    return false;
  }

  let promise;

  if (rejectOnTileFail) {
    promise = requestPromise.then(createInterpolateFunction(tileRequest));
  } else {
    promise = requestPromise
      .then(createInterpolateFunction(tileRequest))
      .catch(createMarkFailedFunction(tileRequest));
  }

  // remove the request we've just done from the queue
  //  and add its promise result to the result list
  tileRequests.shift();
  results.push(promise);

  // indicate we should synchronously attempt the next request as well
  return true;
}
@param {object[]} tileRequests The mutated list of requests, the first one will be attempted
@param {Array<Promise<void>>} results The list to put the result promises into
@param {boolean} rejectOnTileFail If true, the promise will be rejected.  If false, returned heights will be undefined.
@returns {boolean} true if the request was made, and we are okay to attempt the next item immediately,
 or false if we were throttled and should wait awhile before retrying.

@private