0

如果再次调用 Javascript 函数时它仍在运行,我该如何杀死它?

情况是这样的。我有一个具有搜索功能的 HTML5 Android 应用程序。当用户键入时,它会在 HTML5 数据库中搜索匹配项。搜索框中的每次击键都会触发一个功能以获取建议。但是由于用户的输入速度比数据库引擎在相对较慢的设备(比如我自己的,或者实际上是模拟器)上返回建议的速度更快,因此后续按键会排队,因此建议可能需要一段时间才能与用户输入的内容相匹配.

所以我想做的是找到某种方法来终止之前对 getSuggestions 函数的调用,如果在完成之前再次调用它。

很容易设置一个全局函数,该函数在各个阶段进行测试并在看到它时中止,但这不会阻止数据库引擎中堆积的查询,我猜这可能是发生阻塞的地方。这就是为什么我正在寻找某种方法来杀死整个功能。

4

2 回答 2

3

听起来你想要underscore.js debounce 方法

基本上你会像这样使用它:(为简洁起见,使用 jQuery)

$('#searchfield').keyup(_.debounce(getSuggestions, 250));

getSuggestions这将仅在事件未触发 250 毫秒时调用该函数。因此,如果您正在打字,在您暂停至少四分之一秒之前,什么都不会发生。

它的工作原理粘贴在下面。它围绕一个函数包装了一堆逻辑并返回一个新函数。函数式编程不是很有趣吗?

  // Returns a function, that, as long as it continues to be invoked, will not
  // be triggered. The function will be called after it stops being called for
  // N milliseconds. If `immediate` is passed, trigger the function on the
  // leading edge, instead of the trailing.
  _.debounce = function(func, wait, immediate) {
    var timeout, result;
    return function() {
      var context = this, args = arguments;
      var later = function() {
        timeout = null;
        if (!immediate) result = func.apply(context, args);
      };
      var callNow = immediate && !timeout;
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
      if (callNow) result = func.apply(context, args);
      return result;
    };
  };
于 2012-11-11T00:33:14.677 回答
1

由于 JavaScript 是单线程的,因此不可能中断函数的执行。浏览器将简单地“冻结”直到函数返回。事实上,您甚至无法设置全局变量。

因此,您需要做的是将搜索分解成小块(例如,一次搜索 1% 的数据库)。确保每件作品在任何设备上执行的时间不超过 100 毫秒。然后使用 SetTimeout(getSomeMoreSuggestions, 0) 继续调用浏览器事件循环中不同部分的搜索函数。

然后,您可以在每次重新安排下一次执行搜索之前(即在 SetTimeout 之前)检查用户是否对编辑框进行了更改。

于 2012-11-11T00:38:01.200 回答