Search code examples
javascriptjsonforeachxmlhttprequestdelay

Delay for a XMLHTTP Request


Ιs there any convenient way to make XMLHTTP Request in Javascript? Wait for example 3 seconds before sending? I have an array full names

var items = [
    { url: "www.google.com/getChocolate", name: "Chocholate"},
    { url: "www.google.com/getCake", name: "Cake"},
    { url: "www.google.com/getCookie", name: "Cookie"},
];

for (var i = 0; i < items.length; i++) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (this.readyState == 4 && this.status == 200) {
            var data;
            data = JSON.parse(xhr.responseText);
            // processing data here
        }
    };
    xhr.open("GET", items[i].url, false);
    xhr.send();
    // I somehow have to force to send the request for each item only every 3 seconds
}

And for each of them I want to receive JSON response from a server, but it bans me for sometime if i send requests too often, so I need to send them like every 3 seconds, wait for response, process the response and start a new one. I guess I'll have to make it synchronous, so I already put there false argument in xhr.open.


Solution

  • H i friend,

    I just saw your post and I understand that you want to do a request queue - send the first request after 3 seconds and wait it to complete then send next and next till the end of the queue.

    I made a very simple class Request and RequestManager which will do this for you.

    Have a look on the code and let me know if something is unclear to you. Try to read the comments also.

    var items = [{
        url: "www.google.com/getChocolate",
        name: "Chocholate"
      },
      {
        url: "http://en.wikipedia.org/w/api.php?action=opensearch&format=json&limit=15&origin=*&search=cake",
        name: "Cake"
      },
      {
        url: "http://en.wikipedia.org/w/api.php?action=opensearch&format=json&limit=15&origin=*&search=cookie",
        name: "Cookie"
      },
    ];
    
    /* First prepare array of requests that later will be send */
    var requests = [];
    for (var i = 0; i < items.length; i++) {
      requests.push(new Request(items[i].url));
    }
    
    /* Initialize the object that will be responsible for 
     * request sending and process the requests  */
    var manager = new RequestManager(requests);
    manager.process();
    manager.onSend(function(url, response) {
      /* this code will fire once a request is completed, no matter if success of failed */
      console.log('request to ' + url + ' completed ....');
      console.log('----------------------------------------');
    })
    
    
    /**
     * This class is a wrapper that will hold the request
     * and will be responsible to send it with a delay of 3 seconds
     * 
     * @param {string} url - this is the url which is going to be requested
     * @returns {Request} - new Request object
     */
    function Request(url) {
      var that = this, resolve, reject;
      that.url = url;
    
      that.promise = new Promise((res, rej) => {
        resolve = res;
        reject = rej;
      });
    
      that.xhr = new XMLHttpRequest();
      that.xhr.onreadystatechange = function() {
        if (that.xhr.readyState == 4) {
          if (that.xhr.status == 200) {
            var data = null;
            try {
              data = JSON.parse(that.xhr.responseText);
              resolve(data);
            } catch (e) {
              reject(e);
            }
          } else {
            reject({
              statusText: that.xhr.statusText,
              response: that.xhr.response
            });
          }
        }
      };
    
      that.send = function() {
        /* send request after 3 seconds */
        setTimeout(function() {
          that.xhr.open("GET", that.url, true);
          that.xhr.send();
        }, 3000)
    
        return this;
      }
    }
    
    
    /**
     * This class is responsible for processing all the request
     * The main role is to call the Request's send method, 
     * wait the request to complete and then call the next request from the queue
     * until all the requests are processed
     * 
     * @param {Array} requests - this is an array of Request objects
     * @returns {RequestManager} new RequestManager object
     */
    function RequestManager(requests) {
      var that = this,
        callback;
      that.requests = requests;
    
      that.onSend = function(cb) {
        callback = cb;
      }
    
      that.process = function() {
        console.log('Starting requests sending .......');
        doRequestRecursive(that.requests.pop());
      }
    
      function doRequestRecursive(request) {
        request.send().promise.then(function(data) {
          console.log('request ' + request.url + ' success ...');
          callback(request.url, data);
        }, function(err) {
          console.log('request ' + request.url + ' failed ...');
          callback(request.url, err);
        }).then(function() {
          var nextRequest = that.requests.pop();
          if (nextRequest) {
            doRequestRecursive(nextRequest);
          }
        });
      }
    }

    The sample code snippet is sending requests to Wikipedia to demonstrate that they are succeeding because your links are not working ones.