javascript - 如何解决去抖用户输入的竞争条件?

标签 javascript

例如,假设页面根据去抖动的用户文本返回搜索结果。

如何解决端点具有高度可变延迟的情况,其中第二个调用可以在第一个调用之前返回。

例如

用户正在输入“书籍和电影”,按键反跳为 500 毫秒

用户在中间稍微停顿,因此字符串是“books”,这会触发搜索调用。

用户继续输入并完成,触发第二个调用“书籍和电影”。

第二个调用首先返回,根据“书籍和电影”填充列表。

然后,延迟的第一个调用返回并根据“图书”重新呈现列表。

用户只看到“书籍”并且感到困惑。

解决此问题的可靠方法是使用按钮手动触发调用。我想避免这种情况,所以我增加了去抖,但我想知道是否有更好的方法。

最佳答案

我们假设您使用 jQuery 进行 ajax 调用。

一种解决方案是使用池系统:基本上是一个包含 ajax 请求的数组。 每次发出新请求时,您都会中止池中的所有请求。 因此,您可以确保最后发出的请求将是唯一会结束的请求。

这是池的实现:

jQuery.xhrPool = [];
jQuery.xhrPool.abortAll = function () {
    jQuery(this).each(function (idx, jqXHR) {
        jqXHR.abort();
    });
    jQuery.xhrPool.length = 0;
};

以下示例介绍了如何将其与 GitHub ( https://developer.github.com/v3/search/#search-repositories ) 中的“搜索存储库 API”一起使用:

jQuery.xhrPool = [];
jQuery.xhrPool.abortAll = function () {
  jQuery(this).each(function (idx, jqXHR) {
    jqXHR.abort();
  });
  jQuery.xhrPool.length = 0;
};


$(document).ready(function(){
  $("#SearchField").autocomplete({
    source: function( request, response ) {
        // First we abort all other request
        jQuery.xhrPool.abortAll();
      
        $.ajax({
          url: "https://api.github.com/search/repositories",
          method: "get",
          dataType: "jsonp",
          data: {
            q: request.term
          },
          beforeSend: function (jqXHR) {
            // Before sending the request we add it to the pool. 
            jQuery.xhrPool.push(jqXHR);
          },
          success: function(data) {
            var items = new Array();
            for(var i=0;i<data.data.items.length;i++)
            {
              items.push(data.data.items[i].name);
            }
            response(items);
          }
        });
      },
      minLength: 3,
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.css" >
<input type="text" id="SearchField" />

关于javascript - 如何解决去抖用户输入的竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37105255/

相关文章:

javascript - 获取 <s :select> in javascript 的选定列表值

javascript - 为什么我的普通 JS 循环不将值相加来填充新对象?

php - 数据传输和密码加密的提案

javascript - 我们可以从数据库中获取值并将它们显示在 javascript 的选择框中吗

javascript - Discord JS 音乐机器人的问题

javascript - 如何让 Pdf.js 在网页上运行?

javascript - jQuery live() 在 Firefox 中不显示文本光标

javascript - 在 For 循环中将 PHP 变量存储到 JavaScript 变量中

javascript - 有没有办法在以下上下文中伪造 React JS 中的循环动画?

javascript - Canvas 图片麻烦