搜索框中的异步 ajax 调用
Asynchronous ajax calls in a search box
我几个月前为一位客户开发了一个 asp.net 解决方案,我们在其中的输入框中使用了 AzureSearch。我的方法是在用户最后一次击键后每秒发送一次 ajax 请求。但是我们的客户希望它总是在输入框发生变化时发生,所以我们做到了。
这导致客户端报告错误 - 不一致的搜索。这是因为竞争条件,我记录了异步调用,这就是发生的事情。我正在考虑为 javascript 自动完成添加 0.5 秒的延迟。或者,还有更好的方法?就像在 javascript 有一个游泳池。我们使用的控件是 jquery easy autocomplete。
您正在做的事情叫做 "debounce"。去抖动是当您让计时器在用户开始输入时开始倒计时。如果他们在计时器结束前输入更多信息,计时器将重置并再次开始倒计时。只有当计时器结束时,才会进行 AJAX 调用。在这种情况下,研究表明 200 毫秒的延迟是大多数人认为仍然有反应的延迟。
但是,如果您真的希望在用户输入时输入结果,您需要的是 "throttle"。油门类似于去抖动,只是它定期触发,而不是等待输入停止。要构建一个,您仍然需要一个计时器,但是,您不会在每次用户输入更多内容时重置它。相反,您将使用布尔值来跟踪是否输入了新的输入。当计时器完成时,它会检查布尔值是否为真,如果是,则将其设置为假并重新启动计时器倒计时。
您可以通过跟踪 AJAX 调用是否已经发生来改进任一方法。在这两种情况下,如果计时器用完并且布尔跟踪是否正在进行呼叫为真,请重新启动计时器。
这两个 debounce and throttle 已经在几个实用程序库中可用,例如 lodash。您可以使用它们来包装现有的事件处理程序。
var myInputChangeHandler = function() {
// do ajax call
};
// throttled handler will only be called every 200 ms...
var throttled = _.throttle(myInputChangeHandler, 200);
// ...no matter how many times this event fires
jQuery('input[type=text]').on('change', throttled);
最后我没有加延迟或油门。通过查看它的官方网站,我发现了 jquery-easy-autocomplete 中两个非常有用的属性,它们是:
matchResponseProperty:为了避免竞争条件,由于最后一个 ajax 调用不一定是来自后端服务的最后一个响应,它将采用具有 属性 根据此属性指定的名称,与输入中的当前文本匹配。
listLocation:我试图渲染一个 json 和一个匿名的项目列表和一个名为 InputPhrase 的 属性,直到我遇到这个,所以我指定了列表基本响应对象中的位置并将此模型用于响应。
public class SearchViewModel
{
public List<dynamic> Items { get; set; }
public string InputPhrase { get; set; }
}
最后,我将 matchResponseProperty 设置为 "InputPhrase",并将 listLocation 设置为 "Items"
我几个月前为一位客户开发了一个 asp.net 解决方案,我们在其中的输入框中使用了 AzureSearch。我的方法是在用户最后一次击键后每秒发送一次 ajax 请求。但是我们的客户希望它总是在输入框发生变化时发生,所以我们做到了。
这导致客户端报告错误 - 不一致的搜索。这是因为竞争条件,我记录了异步调用,这就是发生的事情。我正在考虑为 javascript 自动完成添加 0.5 秒的延迟。或者,还有更好的方法?就像在 javascript 有一个游泳池。我们使用的控件是 jquery easy autocomplete。
您正在做的事情叫做 "debounce"。去抖动是当您让计时器在用户开始输入时开始倒计时。如果他们在计时器结束前输入更多信息,计时器将重置并再次开始倒计时。只有当计时器结束时,才会进行 AJAX 调用。在这种情况下,研究表明 200 毫秒的延迟是大多数人认为仍然有反应的延迟。
但是,如果您真的希望在用户输入时输入结果,您需要的是 "throttle"。油门类似于去抖动,只是它定期触发,而不是等待输入停止。要构建一个,您仍然需要一个计时器,但是,您不会在每次用户输入更多内容时重置它。相反,您将使用布尔值来跟踪是否输入了新的输入。当计时器完成时,它会检查布尔值是否为真,如果是,则将其设置为假并重新启动计时器倒计时。
您可以通过跟踪 AJAX 调用是否已经发生来改进任一方法。在这两种情况下,如果计时器用完并且布尔跟踪是否正在进行呼叫为真,请重新启动计时器。
这两个 debounce and throttle 已经在几个实用程序库中可用,例如 lodash。您可以使用它们来包装现有的事件处理程序。
var myInputChangeHandler = function() {
// do ajax call
};
// throttled handler will only be called every 200 ms...
var throttled = _.throttle(myInputChangeHandler, 200);
// ...no matter how many times this event fires
jQuery('input[type=text]').on('change', throttled);
最后我没有加延迟或油门。通过查看它的官方网站,我发现了 jquery-easy-autocomplete 中两个非常有用的属性,它们是:
matchResponseProperty:为了避免竞争条件,由于最后一个 ajax 调用不一定是来自后端服务的最后一个响应,它将采用具有 属性 根据此属性指定的名称,与输入中的当前文本匹配。
listLocation:我试图渲染一个 json 和一个匿名的项目列表和一个名为 InputPhrase 的 属性,直到我遇到这个,所以我指定了列表基本响应对象中的位置并将此模型用于响应。
public class SearchViewModel { public List<dynamic> Items { get; set; } public string InputPhrase { get; set; } }
最后,我将 matchResponseProperty 设置为 "InputPhrase",并将 listLocation 设置为 "Items"