jQuery UI 自动完成:中止请求
Posted
技术标签:
【中文标题】jQuery UI 自动完成:中止请求【英文标题】:jQuery UI Autocomplete: Aborting the request 【发布时间】:2011-09-21 16:29:52 【问题描述】:我正在使用执行 ajax 请求的 source
选项的回调版本。我认为如果用户在 ajax 请求完成之前快速连续键入一堆字母,我们应该中止旧的,只使用新的。我假设 source
参数的 URL 版本会自动执行此操作,但由于我使用的是自定义回调,因此我必须手动执行此操作。
这就是我所拥有的:
$('#myselector').autocomplete(
source: function(request, response)
var data = ;
if($(this).data('xhr'))
console.log('aborting...');
$(this).data('xhr').abort();
// *snip* add some stuff to data
$(this).data('xhr', $.ajax(
url: '/ajax/major_city',
dataType: 'json',
data: data,
success: function(data, textStatus, $xhr)
response(data);
,
complete: function($xhr, textStatus)
console.log(textStatus);
if(textStatus === 'abort')
console.log('aborted!');
response([]);
));
,
// ....
因此,每当触发“源”回调时,它都会检查该输入是否存在 XHR 元素(第一次将未定义),如果存在,则中止它(附带问题:如何检查请求是否完成?尝试中止已经完成的请求是没有意义的)。
但是the docs say:
在请求期间提供自定义源回调以处理错误时,这一点很重要。即使遇到错误,您也必须始终调用响应回调。这可确保小部件始终具有正确的状态。
因此,在我的代码底部,您会看到我(尝试)检查请求是否已中止,如果是,则返回一个空列表。但是那个“流产了!” log 似乎永远不会被调用。即使它被中止,它也总是说“成功”。这是为什么呢?
编辑:刚刚尝试输出$(this).data('xhr').readyState
。它似乎永远不会小于4
,这表明source
在最后一个请求返回响应之前不会再次被调用。真可惜,因为我们可以提前中止请求并加快响应时间...
【问题讨论】:
【参考方案1】:bdparrish 有正确的想法
增加插件在发送请求之前的等待时间:
$( ".selector" ).autocomplete( delay: 500 ); //default is 300
这样,您只会在怀疑用户完成输入后才发送请求。发出更少的 http 请求总比发出很多然后取消它们要好。
-莱德杰
【讨论】:
这不是一个真正的解决方案 IMO。它可能有助于缓解问题,但无论您将延迟设置为什么,它们都可能会在一毫秒后按下另一个键。此外,您正在牺牲响应时间来减少请求数量。我可以以大约 100 WPM 的速度打字,我认为这大致相当于每 150 毫秒 1 个字符,因此我想将延迟设置为略高于此。最后,不管这个答案的合法性如何,你都没有解决为什么 abort 没有触发回调的问题。 如果您正确实现了插件,所有请求都将被困在完整的函数中。然后由您在按下另一个键时“中止”运行代码。状态码不会中止,因为您没有告诉服务器您正在这样做。如果你想让它像那样工作,抓住请求的成功返回,然后什么都不做。【参考方案2】:您是否有理由无法设置时间间隔来等待用户“看起来”好像他们已经完成了输入? 'delay' 选项设置在输入最后一个字母之后在搜索之前等待的毫秒数。
此外,即使您从服务器返回“abort”,响应仍然会成功。因为请求没有在服务器上出错。你返回我假设的值'abort'。
【讨论】:
我不太确定你的第一段要表达什么。我想降低延迟并中止旧请求以缩短响应时间。如果用户输入太慢(超过延迟),它可能会在他点击下一个字母之前触发一个 ajax 请求。该请求现在不再有效,因此应该立即中止它,这样我们就不必等待该请求完成后再开始下一个请求。 不,我不会返回“中止”。文档特别说 textStatus 可以是“成功”、“未修改”、“错误”、“超时”、“中止”或“解析错误”之一。我假设当我中止请求时我会得到一个“中止”的文本状态,所以这就是我正在听的。但是鉴于我从来没有机会中止,因为直到前一个事件成功返回之前甚至没有触发下一个事件,所以这一点没有实际意义。以上是关于jQuery UI 自动完成:中止请求的主要内容,如果未能解决你的问题,请参考以下文章
如何实现类似于 jQuery UI 自动完成的 Dojo 自动完成?