DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Snippets has posted 5883 posts at DZone. View Full User Profile

OnlyOneOfClass: Extension To Prototype Library Allowing AJAX Calls To Supercede / Abort / Cancel Previous Calls Within A Given Class.

  • submit to reddit
// Extension to Ajax allowing for classes of requests of which only one (the latest) is ever active at a time
// - stops queues of now-redundant requests building up / allows you to supercede one request with another easily.

// just pass in onlyLatestOfClass: 'classname' in the options of the request

Ajax.currentRequests = {};

	onCreate: function(request) {
		if (request.options.onlyLatestOfClass && Ajax.currentRequests[request.options.onlyLatestOfClass]) {
			// if a request of this class is already in progress, attempt to abort it before launching this new request
			try { Ajax.currentRequests[request.options.onlyLatestOfClass].transport.abort(); } catch(e) {}
		// keep note of this request object so we can cancel it if superceded
		Ajax.currentRequests[request.options.onlyLatestOfClass] = request;
	onComplete: function(request) {
		if (request.options.onlyLatestOfClass) {
			// remove the request from our cache once completed so it can be garbage collected
			Ajax.currentRequests[request.options.onlyLatestOfClass] = null;


Nick Kijak replied on Fri, 2007/04/13 - 10:32am

Now I'm not sure if my code is "broken". It seems that the request returns before it can be canceled and what I was seeing was the delay in writing to the page.

Nick Kijak replied on Fri, 2007/04/13 - 10:32am

Does this snippet work absolutely? Are the requests that get passed to the functions the actual requests or just copies? I've tried this variation that will cancel queued requests, but it seems to only cancel copies and the actual requests remain. (firebug required) /** Array of requests that can be canceled */ Ajax.cancelableRequests = []; /** Registers Ajax.Requests global onCreate and onComplete events */ Ajax.Responders.register({ /** Checks for the 'cancelableRequest' option and adds it to the array if not null */ onCreate: function(request) { if (request.options.cancelableRequest) { request.options.cancelableRequest = new Date().getTime();"creating request. "+request.options.cancelableRequest); Ajax.cancelableRequests.push(request); console.log(Ajax.cancelableRequests.length); } }, /** Looks for the request in the array and removes it */ onComplete: function(request) { console.log("request complete. "+request.options.cancelableRequest); var i = -1; var found = false; for(i = 0; i < Ajax.cancelableRequests.length; i++) { if (Ajax.cancelableRequests[i].options.cancelableRequest == request.options.cancelableRequest) { console.log("found request at "+i); found = true; break; } } if (found) Ajax.cancelableRequests.splice(i, 1); } }); What I am doing is finding all requests with cancelableRequest in the options, making the value for cancelableRequest the time in milliseconds for identification later, then adding it to a array. On complete I am then looking through that array for a matching cancelableRequest value and removing it from the array. I have a function that I call that loops through the array and calls abort on each request. When I run this code I get my canceled log messages for a request followed by a completed message which should never happen if it was really canceled.