I have a backbone application that has a number of views. Switching between views triggers Ajax requests to get different collections. I would like to stop the current "read" ajax request if a new one is started. Is it possible?
Asked
Active
Viewed 1.0k times
3 Answers
38
Ok so here is what I did
I am saving the the fetch requests in a variable
app.fetchXhr = this.model.fetch();
In my router, I have a function that takes care of closing the views and rendering views. It also takes care of triggering any triggers needed for each view change but that is not relevant in this question.
Before doing anything, this router function executes the following
//Stop pending fetch
if(app.fetchXhr.readyState > 0 && app.fetchXhr.readyState < 4){
app.fetchXhr.abort();
}
I hope this helps
-
I have a related issue but I have more than one collection. So before I abort a request I need to be sure that it is associated with a specific collection. I asked that question here, maybe you've already tackled this issue as well? http://stackoverflow.com/questions/21919690/association-between-backbone-collection-and-xhr-object-created-when-fetching – wuliwong Feb 20 '14 at 21:19
-
Didn't to implement this yet but one thing you can try is to store all xhr requests in an array. On each xhr request or on each view change you can loop through the array to clear out those that are complete and to stop those that you want to stop. That should provide an adequate cleanup. – Xerri Feb 21 '14 at 17:25
11
Yet another late reply in case someone else runs into this.
I ended up overwriting Backbone.sync to add a XHR object pool and an option to abort pending requests on fetch.
var sync = Backbone.sync
, xhrPool = [];
Backbone.sync = function(method, model, options) {
options = options || {};
if (method === 'read') {
if (options.abortPending == true) {
for (var i = 0; i < xhrPool.length; i++) {
if (xhrPool[i]['readyState'] > 0 && xhrPool[i]['readyState'] < 4) {
xhrPool[i].abort();
xhrPool.splice(i, 1);
}
}
}
// cleanup xhrPool
// todo: make removal from the pool an 'always' jqXHR callback
// instead of cleanup on every read?
for (var i = 0; i < xhrPool.length; i++) {
if (xhrPool[i]['readyState'] === 4) {
xhrPool.splice(i, 1);
}
}
var xhr = sync(method, model, options);
xhrPool.push(xhr);
return xhr;
} else {
return sync(method, model, options);
}
};

Garrett Johnson
- 800
- 7
- 10
-
Very cool....might not be flexible if you do multiple fetch requests in a particular view. FYI...One of the reasons I needed this was to avoid having errors thrown when a fetch is complete but the view has changed (so the DOM element that would have contained the data is no longer there). A simple try/catch around the fetch fixed this. – Xerri Aug 05 '13 at 10:06
5
I assume you're using backbone with jQuery. If so, the following question seems to provide an answer for you:
Abort Ajax requests using jQuery
Backbone fetch
returns the xhr
they're talking about, IIRC.
-
but wouldn't fetch return xhr after it was complete? Not sure how to use the link you provided to implement it in Backbone – Xerri Oct 08 '12 at 08:31
-
Backbone uses normal ajax calls (through Zepto or jQuery), which means the call to the server is asynchronous and can still potentially be terminated. – JayC Oct 08 '12 at 14:58