Skip to content

Instantly share code, notes, and snippets.

@maccman
Last active January 13, 2018 12:03
Show Gist options
  • Save maccman/5790509 to your computer and use it in GitHub Desktop.
Save maccman/5790509 to your computer and use it in GitHub Desktop.
Queueing jQuery Ajax requests. Usage $.ajax({queue: true})
$ = jQuery
queues = {}
running = false
queue = (name) ->
name = 'default' if name is true
queues[name] or= []
next = (name) ->
list = queue(name)
unless list.length
running = false
return
[options, deferred] = list.shift()
$.ajax(options)
.always(-> next(name))
.done(-> deferred.resolve(arguments...))
.fail(-> deferred.reject(arguments...))
push = (name, options) ->
list = queue(name)
deferred = $.Deferred()
list.push([options, deferred])
next(name) unless running
running = true
deferred.promise()
remove = (name, options) ->
list = queue(name)
for [value, _], i in list when value is options
list.splice(i, 1)
break
$.ajaxTransport '+*', (options) ->
if options.queue
queuedOptions = $.extend({}, options)
queuedOptions.queue = false
queuedOptions.processData = false
send: (headers, complete) ->
push(options.queue, queuedOptions)
.done (data, textStatus, jqXHR) ->
complete(jqXHR.status,
jqXHR.statusText,
text: jqXHR.responseText,
jqXHR.getAllResponseHeaders())
.fail (jqXHR, textStatus, errorThrown) ->
complete(jqXHR.status,
jqXHR.statusText,
text: jqXHR.responseText,
jqXHR.getAllResponseHeaders())
abort: ->
remove(options.queue, queuedOptions)
// Generated by CoffeeScript 1.6.2
(function() {
var $, next, push, queue, queues, remove, running;
$ = jQuery;
queues = {};
running = false;
queue = function(name) {
if (name === true) {
name = 'default';
}
return queues[name] || (queues[name] = []);
};
next = function(name) {
var deferred, list, options, _ref;
list = queue(name);
if (!list.length) {
running = false;
return;
}
_ref = list.shift(), options = _ref[0], deferred = _ref[1];
return $.ajax(options).always(function() {
return next(name);
}).done(function() {
return deferred.resolve.apply(deferred, arguments);
}).fail(function() {
return deferred.reject.apply(deferred, arguments);
});
};
push = function(name, options) {
var deferred, list;
list = queue(name);
deferred = $.Deferred();
list.push([options, deferred]);
if (!running) {
next(name);
}
running = true;
return deferred.promise();
};
remove = function(name, options) {
var i, list, value, _, _i, _len, _ref, _results;
list = queue(name);
_results = [];
for (i = _i = 0, _len = list.length; _i < _len; i = ++_i) {
_ref = list[i], value = _ref[0], _ = _ref[1];
if (!(value === options)) {
continue;
}
list.splice(i, 1);
break;
}
return _results;
};
$.ajaxTransport('+*', function(options) {
var queuedOptions;
if (options.queue) {
queuedOptions = $.extend({}, options);
queuedOptions.queue = false;
queuedOptions.processData = false;
return {
send: function(headers, complete) {
return push(options.queue, queuedOptions).done(function(data, textStatus, jqXHR) {
return complete(jqXHR.status, jqXHR.statusText, {
text: jqXHR.responseText
}, jqXHR.getAllResponseHeaders());
}).fail(function(jqXHR, textStatus, errorThrown) {
return complete(jqXHR.status, jqXHR.statusText, {
text: jqXHR.responseText
}, jqXHR.getAllResponseHeaders());
});
},
abort: function() {
return remove(options.queue, queuedOptions);
}
};
}
});
}).call(this);
@ashanbrown
Copy link

I'm wondering why "running" is shared between all the queues. Seems like if you submitted a request to one queue while another queue was active, then you'd never actually run that request, since the completion of a request on a different queue will not, as far as I can see, send any requests from a different queue. To do that, you'd need some sort of global queue or an arbiter of some sort.

I've forked this gist to store the number of running jobs per queue and also to allow a specified number of concurrent requests. It doesn't attempt to manage a global limit on the number of requests. See my changes at:

https://gist.github.com/dontfidget/1ad9ab33971b64fe6fef

Thanks for sharing this code.

@bitnosis
Copy link

bitnosis commented Aug 8, 2014

This is firing my ajax requests twice now. Any ones that I add {queue:true} to now, get fired twice?? Why would this be?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment