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 自动完成替换某些字符

jquery UI 自动完成:我克隆的自动完成字段不起作用

jQuery-ui 自动完成,选择第一项

如何实现类似于 jQuery UI 自动完成的 Dojo 自动完成?

jQuery UI 自动完成与类似 Chrome 的自动填充

单独更改 jquery-ui 自动完成小部件的宽度