0

再度呼び出されたときにまだ実行中の Javascript 関数を強制終了するにはどうすればよいですか?

状況はこうです。検索機能を備えた HTML5 Android アプリがあります。ユーザーが入力すると、HTML5 データベースで一致するものが検索されます。検索ボックスでキーを押すたびに、候補を取得する機能が起動されます。しかし、データベースエンジンが比較的遅いデバイス(私自身の、または実際にはエミュレーターなど)で提案を返すよりも、ユーザーはより速く入力できるため、後続のキープレスがキューに入れられ、提案がユーザーの入力と一致するまでに時間がかかる場合があります。 .

したがって、私がやりたいことは、終了する前に再度呼び出された場合に、getSuggestions 関数の以前の呼び出しを無効にする何らかの方法を見つけることです。

関数がさまざまな段階でテストし、それが検出された場合に中止するグローバルを設定するのは簡単ですが、データベースエンジンでクエリが山積みになるのを止めることはできません。そのため、機能全体を無効にする方法を探しています。

4

2 に答える 2

3

underscore.js debounce メソッドが必要なようです

基本的には、次のように使用します: (簡潔にするために jQuery を使用)

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

これによりgetSuggestions、イベントが 250 ミリ秒発生しなかった場合にのみ関数が呼び出されます。したがって、入力している場合は、少なくとも 4 分の 1 秒間停止するまで何も起こりません。

それがどのように機能するかを以下に貼り付けます。関数の周りに一連のロジックをラップし、新しい関数を返します。関数型プログラミングは楽しくないですか?

  // 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 に答える