I have to search through word index tables with potentially hundreds of thousands rows. I can restrict my search by passing a list of documents to the search. Request to search for words in many documents return very slowly. So...to improve the UX we're chunking the request into several groups of documents. So, if a user asks to search 90 documents, and the chunk size is 10 documents per query, then we send out 90 / 10 = 9 independent $.ajax() calls. We want the results to come in the order they were sent.
We implement this recursion:
var SearchFunction = function () {
$.ajax(/* ... */);
}
var RecursiveSearch = function () {
var deferred = $.Deferred();
if (arrTransSearch.length > 0) {
deferred = SearchDocuments(arrTransSearch.shift());
}
else {
deferred.reject();
}
return deferred.promise().then(RecursiveSearch);
}
if (arrTransSearch.length > 1) {
RecursiveSearch().fail(SomeFunction);
}
var SomeFunction = function () {
alert("Failed. Yes!");
}
When I debug the code, it appears that deferred.reject()
does not change the state of deferred.promise()
. That is, when the next line
return deferred.promise().then(RecursiveSearch)
is executed, it just loops back into the recursive function, instead of exiting the recursion and falling into
RecursiveSearch().fail(SomeFunction);
Important Note:
I'm using jQuery-1.7.1. I ran analogous recursion in JSFiddle (Thank you Beeetroot-Beetroot) and it failed on jQuery-1.7.2 while on jQuery-2.1.0 it ran without a problem.
Any idea on how to get the recursion to work in jQuery-1.7.1?
A pattern partly covering what you are looking for is provided here under the heading "The Collection Kerfuffle". You actually need slightly more than that because you want to address your list of document referneces in chunks (groups).
The code will be something like this :
You also need the Polyfill for Array.prototype.reduce, as .reduce is relied on above and older browsers (pre ECMAScript5) don't have it.
All untested but I recently answered a similar question here, with a link to a fiddle.
It turns out that until jQuery-1.8, calling
$.then()
with one argument was the equivalent of calling$.then(successFunction, successFunction)
. Since I was using jQuery-1.7.1, a rejected promise would still invoke the recursion.