Javascript 无法使用$.Deffered()对象和$.then()中断递归

Javascript 无法使用$.Deffered()对象和$.then()中断递归,javascript,jquery,recursion,jquery-deferred,jquery-1.7,Javascript,Jquery,Recursion,Jquery Deferred,Jquery 1.7,我必须搜索可能有数十万行的单词索引表。我可以通过向搜索传递文档列表来限制搜索。在许多文档中搜索单词的请求返回得非常慢。所以…为了改进用户体验,我们将请求分块成几个文档组。因此,如果用户要求搜索90个文档,并且块大小是每个查询10个文档,那么我们将发出90/10=9个独立的$.ajax()调用。我们希望结果按照发送顺序来 我们实现这个递归: 调试代码时,deferred.reject()似乎不会更改deferred.promise()的状态。也就是说,下一行是什么时候 return deferre

我必须搜索可能有数十万行的单词索引表。我可以通过向搜索传递文档列表来限制搜索。在许多文档中搜索单词的请求返回得非常慢。所以…为了改进用户体验,我们将请求分块成几个文档组。因此,如果用户要求搜索90个文档,并且块大小是每个查询10个文档,那么我们将发出90/10=9个独立的$.ajax()调用。我们希望结果按照发送顺序来

我们实现这个递归: 调试代码时,
deferred.reject()
似乎不会更改
deferred.promise()
的状态。也就是说,下一行是什么时候

return deferred.promise().then(RecursiveSearch)
执行时,它只是循环回递归函数,而不是退出递归并陷入

RecursiveSearch().fail(SomeFunction);
重要提示: 我正在使用jQuery-1.7.1。我在(谢谢)中运行了类似的递归,它在jQuery-1.7.2上失败,而在jQuery-2.1.0上运行时没有问题


关于如何让递归在jQuery-1.7.1中工作的任何想法?

结果是,在jQuery-1.8之前,调用
$。然后()
使用一个参数相当于调用
$。然后(successFunction,successFunction)
。由于我使用的是jQuery-1.7.1,被拒绝的承诺仍然会调用递归。

在“收集混乱”标题下提供了一个部分覆盖您所寻找内容的模式。实际上,您需要稍微多一些,因为您希望以块(组)的形式处理文档引用列表

代码如下所示:

$(function() {

    //General ajax options for searching a document group
    var ajaxOptions = {
        url: '...',
        type: 'POST',
        //data: ... //added dynamically 
        dataType: 'JSON',
        // etc.
    };

    //
    function searchDocumentsInGroups(arr, n) {
        //Pre-process arr to create an array of arrays, where each inner array is a group of document references
        var groups = [];
        $.each(arr, function (i) {
            if (!(i % n)) groups.push(arr.slice(i, i + n));
        });

        //Ajax serializer (from the Collection Kerfuffle reference)
        return groups.reduce(function (promise, group) {
            return promise.then(function () {
                return $.ajax($.extend({}, ajaxOptions, {
                    data: JSON.stringify(group);//or whatever, compatible with the server-side script
                })).then(function (groupResults) {
                    //display groupResults here
                });
            });
        }, $.when(0));
    }

    // data
    var myDocumentArray = [ 'doc1', 'doc2', 'doc3', 'doc4', 'etc.' ], //Your array of 90 document references.
        groupSize = 10; //Number of documents per "chunk".

    // Event handler to kick off the process.
    $("#searchDocuments").on('click', function () {
        // display "in progress" message or spinner here
        searchDocumentsInGroups(myDocumentArray, groupSize).then(function () {
            // display "complete" message or hide spinner here
        });
    });
});
您还需要Array.prototype.reduce的Polyfill,因为.reduce依赖于上面的版本,而旧版本的浏览器(ECMAScript 5之前)没有

if ( 'function' !== typeof Array.prototype.reduce ) {
  Array.prototype.reduce = function( callback /*, initialValue*/ ) {
    'use strict';
    if ( null === this || 'undefined' === typeof this ) {
      throw new TypeError(
         'Array.prototype.reduce called on null or undefined' );
    }
    if ( 'function' !== typeof callback ) {
      throw new TypeError( callback + ' is not a function' );
    }
    var t = Object( this ), len = t.length >>> 0, k = 0, value;
    if ( arguments.length >= 2 ) {
      value = arguments[1];
    } else {
      while ( k < len && ! k in t ) k++; 
      if ( k >= len )
        throw new TypeError('Reduce of empty array with no initial value');
      value = t[ k++ ];
    }
    for ( ; k < len ; k++ ) {
      if ( k in t ) {
         value = callback( value, t[k], k, t );
      }
    }
    return value;
  };
}
if('function'!==typeof Array.prototype.reduce){
Array.prototype.reduce=函数(callback/*,initialValue*/){
"严格使用",;
if(null==此| |“未定义”==此的类型){
抛出新类型错误(
'Array.prototype.reduce在null或未定义时调用';
}
if('function'!==回调类型){
抛出新类型错误(回调+'不是函数');
}
var t=Object(this),len=t.length>>>0,k=0,value;
如果(arguments.length>=2){
值=参数[1];
}否则{
而(k=len)
抛出新的TypeError(“减少没有初始值的空数组”);
值=t[k++];
}
对于(;k
所有这些都未经测试,但我最近回答了一个类似的问题,其中有一个指向小提琴的链接

if ( 'function' !== typeof Array.prototype.reduce ) {
  Array.prototype.reduce = function( callback /*, initialValue*/ ) {
    'use strict';
    if ( null === this || 'undefined' === typeof this ) {
      throw new TypeError(
         'Array.prototype.reduce called on null or undefined' );
    }
    if ( 'function' !== typeof callback ) {
      throw new TypeError( callback + ' is not a function' );
    }
    var t = Object( this ), len = t.length >>> 0, k = 0, value;
    if ( arguments.length >= 2 ) {
      value = arguments[1];
    } else {
      while ( k < len && ! k in t ) k++; 
      if ( k >= len )
        throw new TypeError('Reduce of empty array with no initial value');
      value = t[ k++ ];
    }
    for ( ; k < len ; k++ ) {
      if ( k in t ) {
         value = callback( value, t[k], k, t );
      }
    }
    return value;
  };
}