Amr Ayoub Amr Ayoub - 1 month ago 10
Javascript Question

ES6 Asynchronous promises

i'm still beginner in ES6 .
i'm trying to create a function which sends a http(s) request with the a logic that when You send a http(s) request. If there is 5 or more ongoing requests, you have to wait until one
of them is completed then you can process next request.
When the response code is not 200, you need to retry 3 times. If the response code after
retrying 3 times is still not 200 then the error function should be executed.
also i wanna Receive the JSON data of the response body as a function argument.

function httpGet(url) {
return new Promise(
function (resolve, reject) {
const request = new XMLHttpRequest();
request.onload = function () {
if (this.status === 200) {
// Success
resolve(this.response);
} else {
// Something went wrong (404 etc.)
reject(new Error(this.statusText));
}
};
request.onerror = function () {
reject(new Error(
'XMLHttpRequest Error: '+this.statusText));
};
request.open('GET', url);
request.send();
});
}


this what i have done so far .
Thanks

Answer

Here's a general queue for promise callbacks:

// Helper to run a callback when a promise either resolves, or rejects.
function fin(promise, callback){
  return promise.then(
    value => (callback(), Promise.resolve(value)),
    error => (callback(), Promise.reject(error))
  );
}

function makeQueue(maxParallel){
  const queue = [];
  let inProgress = 0;

  // Run the oldest queued task.
  function run(){
    const {resolve, reject, callback} = queue.shift();

    inProgress++;
    return fin(callback(), () => inProgress--).then(resolve, reject);
  }

  // If more tasks can run in parallel, start them
  function dequeue(){
    if (queue.length > 0 && inProgress < maxParallel) fin(run(), dequeue);
  }

  return function(callback){
    return new Promise((resolve, reject) => {
      queue.push({resolve, reject, callback});
      dequeue();
    });
  }
}

Then use the queue to queue httpGet:

const queue = makeQueue(5);

// Queue up httpGet calls.
function httpGetWithQueue(url){
  return queue(() => httpGet(url));
}

Then call that with retry logic:

// Call httpGet with queued processing, with the request tried
// up to three times.
function httpGetWithRetry(url){
  let result = Promise.reject();

  for (var i = 0; i < 3; i++){
    result = result.catch(() => httpGetWithQueue(url));
  }
  return result;
}  
Comments