4

<input>次のように、ユーザーが要素に入力したときにサーバーに ajax リクエストを送信しています。

$('#my-input').bind("input", function(event){
   // here's the ajax request
});

私が気になるのは、ユーザーがキーを押すたびに不必要に多くのリクエストを送信することです。つまり、ユーザーが非常に速く入力すると、不要なリクエストが多数発生することになります。したがって、ユーザーがajaxリクエストを送信する前に入力を停止するまで、特定の時間(50ミリ秒?)待機する特定の遅延/タイムアウトが必要であるという考えが得られます。これで問題の 1 つが解決されます。

しかし、別のリクエストを送信する前に最初の ajax リクエストが完了していない場合はどうでしょうか? (ajax リクエストが 300 ミリ秒かかっている間、60 ミリ秒/文字を入力します)。

この問題を解決する最善の方法は何ですか (アイデアベースとコードベースの両方)?

4

4 に答える 4

3

アンダースコア ライブラリでスロットル関数を使用できます。そのドキュメントが言うように:

渡された関数のスロットルされた新しいバージョンを作成して返します。これは、繰り返し呼び出されたときに、実際には待機ミリ秒ごとに最大 1 回だけ元の関数を呼び出します。追いつくことができないほど速く発生するレート制限イベントに役立ちます。

新しいライブラリを導入したくない場合でも、この関数がどのように機能するかをソース コードから理解することができます。実際、throttle関数の単純なバージョンは次のようになります。

function throttle(func, delay) {
    var timeout = null;
    return function() {
        var that = this, args = arguments;
        clearTimeout(timer);
        timeout = setTimeout(function() {
            func.apply(that, args);
        }, delay);
    };
}

この jQueryスロットル デバウンス プラグインも役立ちます。特に、作成者によると、関数は関数debounceよりもニーズに適しているようです。throttle

デバウンスは、AJAX 要求をトリガーするイベントでのハンドラーのレート制限実行に特に役立ちます。

于 2013-01-12T05:21:04.760 に答える
1

setTimeout 関数を使用するだけです。テキストが変更されていないかどうかを時々確認し、変更されていない場合はそれに応じて処理します。

setTimeout(function() {
      // Do something after 1 second
}, 1000);
于 2013-01-12T05:26:28.440 に答える
0

@ HuiZeng 's answerを使用しますが、わずかに変更されたバージョンが必要な場合に備えて。

手順

  1. クリアできる setTimeout を使用して keydown をリッスンします。
  2. 起動したら、以前のリクエストがキューにあるかどうかを確認し、ある場合はそれを中止して新しいリクエストを起動します

例:

var inputTimer = 0, req;

function onInput(e){
      clearTimeout(inputTImer);
      inputTimer = setTimeout( function(){
           // You have access to e here
           // Cancel any previous requests
           req && req.abort();
           req = $.ajax({/*...Do your magic here :)*/})
      }, 100)
 }
于 2013-01-12T08:07:50.990 に答える
0

ajax リクエストで async: false を設定して、最初の ajax リクエストの完了後にのみ 2 番目の ajax 呼び出しを処理することができます。

于 2013-01-12T06:18:27.043 に答える