gpt4 book ai didi

javascript - 无法使用 $.Deferred() 对象和 $.then() 中断递归

转载 作者:行者123 更新时间:2023-12-02 17:31:34 26 4
gpt4 key购买 nike

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

我们实现这个递归:

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!");
}

当我调试代码时,似乎 deferred.reject() 不会更改 deferred.promise() 的状态。即当下一行

return deferred.promise().then(RecursiveSearch)

执行后,只是循环回递归函数,而不是退出递归并陷入

RecursiveSearch().fail(SomeFunction);

重要说明:

我正在使用jQuery-1.7.1。我在 JSFiddle 中运行了类似的递归(谢谢 Beeetroot-Beetroot )它在 jQuery-1.7.2 上失败,而在 jQuery-2.1.0 上运行没有问题。

关于如何让递归在jQuery-1.7.1中工作有什么想法吗?

最佳答案

提供了部分覆盖您正在寻找的内容的模式 here 标题为“The Collection Kerfuffle”。实际上,您需要的稍微多一点,因为您想以 block (组)的形式处理文档引用列表。

代码将是这样的:

$(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,而旧版浏览器(ECMAScript5 之前)没有它。

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;
};
}

全部未经测试,但我最近回答了类似的问题 here ,带有 fiddle 链接。

关于javascript - 无法使用 $.Deferred() 对象和 $.then() 中断递归,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23018273/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com