最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Consecutive Ajax requests without jQuery JS library - Stack Overflow

programmeradmin1浏览0评论

I have an issue, mainly with IE.

I need to be able to handle n queries one after another. But If I simply call my function below in a for loop IE does some strange things (like loading only so many of the calls). If I use an alert box it proves that the function gets all of the calls, and surprisingly IT WORKS!

My guess is that IE needs more time than other browsers, and the alert box does just that.

Here is my code:

 var Ajax = function(all) {
  this.xhr = new XMLHTTPREQUEST(); // Function returns xhr object/ activeX
  this.uri = function(queries) { // Takes an object and formats query string
   var qs = "", i = 0, len = size(queries);
   for (value in queries) {
    qs += value + "=" + queries[value];
    if (++i <= len) { qs += "&"; }
   }
   return qs;
  };
  xhr.onreadystatechange = function() { // called when content is ready
   if (this.readyState === 4) {
    if (this.status === 200) {
     all.success(this.responseText, all.params);
    }
    this.abort();
   }
  };
  this.post = function() { // POST
   xhr.open("POST", all.where, true);
   xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
   xhr.send(uri(all.queries));
  };
  this.get = function() { // GET
   xhr.open("GET", all.where + "?" + uri(all.queries), true);
   xhr.send();
  };
  if (this instanceof Ajax) {
   return this.Ajax;
  } else {
   return new Ajax(all);
  }
 };

This function works perfectly for a single request, but how can I get it to work when called so many times within a loop?

I have an issue, mainly with IE.

I need to be able to handle n queries one after another. But If I simply call my function below in a for loop IE does some strange things (like loading only so many of the calls). If I use an alert box it proves that the function gets all of the calls, and surprisingly IT WORKS!

My guess is that IE needs more time than other browsers, and the alert box does just that.

Here is my code:

 var Ajax = function(all) {
  this.xhr = new XMLHTTPREQUEST(); // Function returns xhr object/ activeX
  this.uri = function(queries) { // Takes an object and formats query string
   var qs = "", i = 0, len = size(queries);
   for (value in queries) {
    qs += value + "=" + queries[value];
    if (++i <= len) { qs += "&"; }
   }
   return qs;
  };
  xhr.onreadystatechange = function() { // called when content is ready
   if (this.readyState === 4) {
    if (this.status === 200) {
     all.success(this.responseText, all.params);
    }
    this.abort();
   }
  };
  this.post = function() { // POST
   xhr.open("POST", all.where, true);
   xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
   xhr.send(uri(all.queries));
  };
  this.get = function() { // GET
   xhr.open("GET", all.where + "?" + uri(all.queries), true);
   xhr.send();
  };
  if (this instanceof Ajax) {
   return this.Ajax;
  } else {
   return new Ajax(all);
  }
 };

This function works perfectly for a single request, but how can I get it to work when called so many times within a loop?

Share Improve this question asked Jan 4, 2010 at 1:58 TomTom 7,0917 gold badges49 silver badges80 bronze badges
Add a ment  | 

4 Answers 4

Reset to default 6

I think the problem might be related to the 2 concurrent connections limit that most web browsers implement.

It looks like the latency of your web service to respond is making your AJAX requests overlap, which in turn is exceeding the 2 concurrent connections limit.

You may want to check out these articles regarding this limitation:

  • The Dreaded 2 Connection Limit
  • The Two HTTP Connection Limit Issue
  • Circumventing browser connection limits for fun and profit

This limit is also suggested in the HTTP spec: section 8.14 last paragraph, which is probably the main reason why most browsers impose it.

To work around this problem, you may want to consider the option of relaunching your AJAX request ONLY after a successful response from the previous AJAX call. This will prevent the overlap from happening. Consider the following example:

function autoUpdate () {
    var ajaxConnection = new Ext.data.Connection();

    ajaxConnection.request({
        method:         'GET',
        url:            '/web-service/', 

        success: function (response) {
            // Add your logic here for a successful AJAX response.
            // ...
            // ...

            // Relaunch the autoUpdate() function in 100ms. (Could be less or more)
            setTimeout(autoUpdate, 100);
        }
    }
}

This example uses ExtJS, but you could very easily use just XMLHttpRequest.

Given that the limit to a single domain is 2 concurrent connections in most browsers, it doesn't confer any speed advantage launching more than 2 concurrent requests. Launch 2 requests, and dequeue and launch another each time one pletes.

I'd suggest throttling your requests so you only have a few (4?) outstanding at any given time. You're probably seeing the result of multiple requests being queued and timing out before your code can handle them all. Just a gess though. We have an ajax library that has built-in throttling and queues the requests so we only have 4 outstanding at any one time and don't see any problems. We routinely q lots per page.

Your code looks like it's put together using the constructor pattern. Are you invoking it with the new operator like var foo = new Ajax(...) in your calling code? Or are you just calling it directly like var foo = Ajax(...) ?

If the latter, you're likely overwriting state on your later calls. It looks like it's designed to be called to create an object, on which the get/post methods are called. This could be your problem if you're "calling it within a loop" as you say.

发布评论

评论列表(0)

  1. 暂无评论