Gracias, Wikipedia.
ShareCode
Permalink: http://www.treeweb.es/u/974/ 01/02/2011

ShareCode

1 /*/////////////////////////////////////////////////////////////////////////////2  //3  AJAX DEFINITION (BEGIN) //4  */5 /**6  * Description: Manage ajax connections with a queue model.7  * Author: gerardooscarjt@gmail.com8  * Date: 2013/31/019  * Typical use:10 11 var ajax = new Ajax();12 ajax.setUrl('http://example.com/path');13 ajax.setMethod('post');14 ajax.setData({'name':'a','age':'22'};15 ajax.callback.done = function(xhr) {16  // ...17 };18 ajax.callback.error = function(xhr) {19  // ...20 };21 ajax.send();22 23 */24 var Ajax = function() {25  26  Ajax.prototype.requests.push(this);27  28  this._id = Ajax.prototype.id_generator;29  Ajax.prototype.id_generator++;30  31  this.callback = {32  done:null,33  error:null,34  progress:null,35  presend:null36  };37  38  this._method = 'get';39  this._async = true;40  this._url = '';41  this._data = null;42  this._retries = 3;43  this._xhr = null;44  this._timeout = 3000;45  46 }47 48 Ajax.prototype.requests = [];49 Ajax.prototype.queue = [];50 Ajax.prototype.id_generator = 0;51 Ajax.prototype.concurrency_limit = 4;52 53 /// METHOD ///54 Ajax.prototype.setMethod = function(method) {55  if (!this.isQueued())56  this._method = method;57 };58 Ajax.prototype.getMethod = function(method) {59  return this._method;60 };61 62 /// URL ///63 Ajax.prototype.setUrl = function(url) {64  if (!this.isQueued())65  this._url = url;66 };67 Ajax.prototype.getUrl = function() {68  return this._url;69 };70 71 /// DATA ///72 Ajax.prototype.setData = function(data) {73  if (!this.isQueued())74  this._data = data;75 };76 Ajax.prototype.getData = function () {77  return this._data;78 };79 80 /// TIMEOUT ///81 Ajax.prototype.setTimeout = function(timeout) {82  this._timeout = timeout;83 };84 Ajax.prototype.getTimeout = function() {85  return this._timeout;86 };87 88 /// IS QUEUED ///89 Ajax.prototype.isQueued = function () {90  return Ajax.prototype.queue.indexOf(this) > -1;91 };92 93 Ajax.prototype.send = function() {94  if (!this.isQueued()) {95  //logger.log(this._id + ' no está en la cola: encolando...');96  ajax_stats[this._id+'.'+this._retries] = {'delay':NaN,'waiting':NaN,'request':NaN,'server_delay':'undefined','status':'queued'};97  ajax_stats[this._id+'.'+this._retries].delay = new Date().getTime();98  Ajax.prototype.queue.push(this);99  Ajax._move();100  } else {101  //logger.log('ya está en la cola'); 102  }103 };104 105 /**106  * Close connection107 */108 Ajax.prototype._close = function() {109  Ajax.prototype.concurrency_limit++;110  this._retries--;111  if (this._retries > 0) {112  this.send();113  }114  Ajax._move();115 116 };117 118 /**119  * Returns true if abort has been performed120 */121 Ajax.prototype.abort = function() {122  if ( null != this._xhr && this._xhr.readyState != 4) {123  // The request is on the way. It must be cancelled124  ajax_stats[this._id+'.'+this._retries].request = new Date().getTime();125  ajax_stats[this._id+'.'+this._retries].status = 'aborted';126 127  this._xhr.abort();128  delete this._xhr;129  this._xhr = null;130  this._retries--;131  Ajax.prototype.concurrency_limit++;132  return true;133  }134  return false;135 };136 137 /// PRIVATE METHODS (I WOULD LIKE) ///138 Ajax.prototype._send = function() {139  var that = this;140  141  //logger.log('Send request for '+this._id);142  143  this._xhr = new XMLHttpRequest({mozSystem:true});144  this._xhr.open(this._method, this._url, this._async);145  this._xhr.timeout = this._timeout;146  147  this._xhr.onreadystatechange = function(event) {148  if(null != that._xhr && that._xhr.readyState == XMLHttpRequest.DONE) {149  ajax_stats[that._id+'.'+that._retries].request = new Date().getTime();150  ajax_stats[that._id+'.'+that._retries].server_delay = that._xhr.responseText;151  if (that._xhr.status == 0) {152  ajax_stats[that._id+'.'+that._retries].status = 'retry';153  } else {154  ajax_stats[that._id+'.'+that._retries].status = 'done';155  results[that._id] = that._xhr.responseText;156  157  that._retries = 0;158  }159  that._close();160  }161  };162  163  this._xhr.onerror = function(event) {164  ajax_stats[that._id+'.'+that._retries].status = 'error';165  that._close();166  };167  168  this._xhr.send();169  ajax_stats[this._id+'.'+this._retries].waiting = new Date().getTime();170  ajax_stats[that._id+'.'+that._retries].status = 'sent';171  172 };173 174 175 /// STATIC METHODS ///176 177 // Abort all current requests178 Ajax._abort_all = function() {179  for (var k in Ajax.prototype.requests) {180  var a = Ajax.prototype.requests[k];181  a.abort() && a.send();182  }183 };184 185 /* Move queue */186 Ajax._move = function() {187  188  if (window.navigator.onLine) {189  while (Ajax.prototype.concurrency_limit > 0 && Ajax.prototype.queue.length > 0) {190  var a = Ajax.prototype.queue.shift();191  ajax_stats[a._id+'.'+a._retries].status = 'unqueued';192  a._send();193  Ajax.prototype.concurrency_limit--;194  }195  }196 };197 198 // Initialize onLine and offLine events199 window.addEventListener('online', function() {200  Ajax._move();201 }, true);202 203 window.addEventListener('offline', function() {204  Ajax._abort_all();205 }, true);206 207  /*208  AJAX DEFINITION (END) //209  //210 /////////////////////////////////////////////////////////////////////////////*/211 212 213 214 var ajax_stats_start = new Date().getTime();215 var ajax_stats = {};216 var line_status = [];217 var results = [];218 219 220 221 222 window.addEventListener('load', function(){223  //test1(); 224  225  // Initialize onLine and offLine events226  window.addEventListener('online', function() {227  line_status.push(new Date().getTime());228  }, true);229  230  window.addEventListener('offline', function() {231  line_status.push(new Date().getTime());232  }, true);233  234  235  log_chart = logger.log('CHAT WILL BE RENDERED HERE');236  237 }, true);238 239 240 /**241  * Launch 20 ajax calls242 */243 function test1() {244  245  ajax_stats_start = new Date().getTime();246  ajax_stats = {};247  results = [];248 249  logger.show();250 251  for (var i=0; i<20; i++) {252  var ajax = new Ajax();253  ajax.setUrl('http://www.treeweb.es/request?e='+ajax._id+'&delay=random');254  ajax.callback.done = function(xhr) {255  logger.log('Completed '+ajax._id);256  };257  ajax.send();258  //logger.log('Launched '+ajax._id);259  }260 261  //logger.log(Ajax.prototype.queue);262  263  see_chart();264 }265 266 /**267  * Launch N fast ajax calls268 */269 function test2(n) {270  271  ajax_stats_start = new Date().getTime();272  ajax_stats = {};273  results = [];274 275  logger.show();276 277  for (var i=0; i<n; i++) {278  var ajax = new Ajax();279  ajax.setUrl('http://www.treeweb.es/request?e='+ajax._id+'&delay=0');280  ajax.callback.done = function(xhr) {281  282  };283  ajax.send();284  }285  see_chart();286 }287 288 function see_stats() {289  290  var s = '';291  292  for (k in ajax_stats) {293  s +=294  '<tr>'295  + '<td>' + (k) + ' (server delay ' + ajax_stats[k].server_delay + ')' + '</td>'296  + '<td>' + (ajax_stats[k].delay - ajax_stats_start) + '</td>'297  + '<td>' + (ajax_stats[k].waiting - ajax_stats[k].delay) + '</td>'298  + '<td>' + (ajax_stats[k].request - ajax_stats[k].waiting) + '</td>'299  + '</tr>';300  }301  302  var h = '<tr> <td>id</td> <td>delay</td> <td>waiting</td> <td>request</td> </tr>';303  s = '<table>' + h + s + '</table>';304  305  logger.log(s);306  logger.show();307 }308 309 var log_chart = null;310 311 312 function see_chart() {313  314  var ts = new Date().getTime();315  316  // Calc maximum time:317  /*318  var max_t = -1;319  var max_w = 1;320  for (k in ajax_stats)321  if (ajax_stats[k].request > max_t) {322  max_t = ajax_stats[k].request;323  max_w = ajax_stats[k].request - ajax_stats_start;324  }325  */326  327  max_w = ts - ajax_stats_start;328  329  var s = '';330  331  for (k in ajax_stats) {332  333  var delay = ajax_stats[k].delay;334  isNaN(delay) && (delay = ts);335  336  var waiting = ajax_stats[k].waiting;337  isNaN(waiting) && (waiting = ts);338 339  var request = ajax_stats[k].request;340  isNaN(request) && (request = ts);341 342 343  var delay_ms = delay - ajax_stats_start;344  var waiting_ms = waiting - delay;345  var request_ms = request - waiting;346  347  //if ( isNaN(ajax_stats[k].request) ) logger.log('NAAAAN');348  349  var delay_rel = (100 * Math.floor(1000*(delay_ms) / max_w ) / 1000);350  var waiting_rel = (100 * Math.floor(1000*(waiting_ms) / max_w ) / 1000);351  var request_rel = (100 * Math.floor(1000*(request_ms) / max_w ) / 1000);352  353  s += ''354  + '<div class="label">' + (k) + ' (' + ajax_stats[k].status + ') ' + '</div>'355  + '<div class="row">'356  + '<div class="bar bar-delay" style="width:' + delay_rel + '%" title="' + delay_rel + '%">' + delay_ms + 'ms</div>' 357  + '<div class="bar bar-waiting" style="width:' + waiting_rel +'%" title="' + waiting_rel +'%">' + waiting_ms + 'ms</div>'358  + '<div class="bar bar-request" style="width:' + request_rel +'%" title="' + request_rel +'%">' + request_ms + 'ms</div>'359  + '<div class="bar bar-end" ><div></div></div>'360  + '</div>';361  }362  363  // Display seconds364  s += ''365  + '<div class="label"> seconds </div>'366  + '<div class="row">';367  var second_width = (100 * Math.floor(1000*(1000) / max_w ) / 1000);368  var c = 0;369  for (var i = ajax_stats_start+1000; i<ts; i+=1000) {370  c++;371  s += '<div class="bar bar-second" style="width:' + second_width + '%">' + c + '</div>' 372  }373  s += '</div>';374  375  s = '<div class="chart">' + s + '</div>';376  377  378  379  var s2 = '';380  for (var i=0; i<results.length; i++) {381  s2 += '<div style="display:inline-block; border:solid silver 1px; padding:4px;">'+i+' ('+results[i]+')</div>';382  }383  s += '<div>'+s2+'</div>';384 385  log_chart.innerHTML = s;386 387  388 389  logger.show();390  if (Ajax.prototype.queue.length > 0)391  setTimeout(function() {392  see_chart();393  }, 500);394 }395 396 
Enlace
El enlace para compartir es: