View Single Post
Old 12-21-2012, 05:34 PM   PM User | #7
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,452
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
here are a few suggestions. ok, several, sorry; i got carried away...


Code:
<!DOCTYPE html>
<html>	<head>
	<title>Page Title</title>
	<style type="text/css">
		#theTable {
			outline: 1px solid gray;
		}
		#theTable td {
			width: 50px;
			height: 50px;
		}
		
	</style>
</head>
<body>
	<h1>10 Asynchronous Ajax Requests</h1>
	<p>Here come the 10 random numbers..</p>

	<div id="theDiv"><progress>Wait..</progress></div>

	<table id="theTable">
		<tr>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
			<td>&nbsp;</td>
		</tr>
	</table>

<script>

  //add "".trim (if needed)
  String.prototype.trim = String.prototype.trim  ||  function() {
  	return this.replace(/^\s+|\s+$/g, '');
  };

function insertData (index, value, obj ) {
  	insertData.tbl = insertData.tbl || document.getElementById(obj.OutputID);
  	(insertData.tbl.rows[0].cells[index] || "").innerHTML = String(value);
}// end insertData ()



function MultiAjax(obj) {
  	this.Pages = obj.Pages || [ obj.Page ];
  	this.StartAfter = obj.StartAfter || Math.floor(this.Pages.length % 2);
  	this.Success = obj.Success;
	this.Base= obj.Base || "";
	this.OutputID=obj.OutputID||"theTable";
  	this.Failure = obj.Failure || this.Success;
  	this.Delays = obj.Delays || 500;
  	this.Results = [];
	var that=this;
 	setTimeout(function(){ that.Go(); }, 100); 
}//end MultiAjax()


function ajax(url, that){
	var req=new XMLHttpRequest();
	var thisOne=that.thisOne;

	req.onreadystatechange = onReady;
	req.open("GET", url, true);
	req.send();

	function onReady() {

		if (req.readyState == 4 && req.status == 200) {
			that.Results.push(thisOne, (req.responseText).trim() * 1);
			if (thisOne == that.StartAfter) {
				// start displaying in the table
				that.updating = setInterval(function() {
					that.currentOne = that.currentOne || 0;
					that.currentOne++;
					if (that.Results.length > 0) {
						that.Success(that.Results.shift(), that.Results.shift(), that );
						console.log("writing", that.results|'');
					} else if (that.currentOne >= that.Limit) {
						clearInterval(that.updating);
					}/* end if(that.Results.length > 0) */
				}, that.Delays);
			} /* end if(thisOne == that.StartAfter) */
		} else if(req.readyState == 4) {
				 that.Failure( that.thisOne , "Err!" + req.status, that );
		} /* end if(req.readyState == 4 .. && 200) */

	} /* end onReady() */
}//end ajax()

  MultiAjax.prototype = {
  	Go: function() {
  		var i = 0, that = this, mx=that.Pages.length;
  		for (;i < mx; i++) {
			that.thisOne=i;
			ajax( that.Base + that.Pages[i] , that );
  		}
  	}
  };

  var thisRun = new MultiAjax({
	Base: 		'createRandomNumber.php?rnd=',
  	Pages: 		'1235,0012,5869,0024,2003,0087,2587,0159,1598,2335'.split(',') ,
  	StartAfter: 	5, 
  	Delays:		500,
	OutputID:	'theTable', 
  	Success:	insertData ,
  	Failure:	insertData
  });
</script>
</body>
</html>
changes
  • @type not needed in html5, removed
  • added <progress> to look nice, fallback to text in older IEs
  • re-indent using tabs (saves >1kb of bandwidth)
  • don't clobber native "".trim() if it's already available.
  • kill Limit, JS can count
  • nesting is confusing, so i move the ajax stuff to a re-usable standalone.
    - if you want to be fancy, it's called "dependency injection", but it basically means passing that so the function works out-of-loop
  • change thisOne to that.thisOne so it's bundled, but shadow it in the ajax so each has it's own copy.
  • mixing this and that is confusing, stick with that for code consistency
  • while is scary and for indeterminate amounts, use a for loop to iterate collections
  • move dom ID to the config object for easier re-use or having more than one instance per page.
  • change brittle firstChild.data to whole-cell .innerHTML to allow rich formatting in future responses.
  • bind the timeout handle to that for easy persistence
  • reduce code by coercing a single page into an array, and always using the array routine
  • why have to call go() each time, let's call it for us.
  • that's a lot of url, a base and suffix so we can pass "1235,0012,5869,0024,2003,0087,2587,0159,1598,2335".split(",")
    - the change shortens the hand-coded part, and is optional if you use full paths and no .Base...
  • new XMLHttpRequest() || new ActiveXObject("Microsoft.XMLHTTP") will fail (throw) in IE6, the only browser that might need ActiveX. screw IE6.
  • remove redundant var statements on functions to allow hoisting

2do
-Capitals imply Constructors, properties and methods should be .camelCase'd() instead
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.8% IE9:11.4% IE10:6.5%

Last edited by rnd me; 12-21-2012 at 05:39 PM..
rnd me is offline   Reply With Quote