1. ホーム
  2. javascript

[解決済み] 無名関数でロダッシュのデバウンスが機能しない

2023-08-04 18:27:32

質問

hello debounce関数が、キーアップイベントに直接渡されると期待通りに動作するのに、無名関数でラップすると動作しないのはなぜなのかがわかりません。

問題のフィドルを持っています。 http://jsfiddle.net/6hg95/1/

編集:試したものをすべて追加しました。

HTML

<input id='anonFunction'/>
<input id='noReturnAnonFunction'/>
<input id='exeDebouncedFunc'/>
<input id='function'/>
<div id='output'></div>

JAVASCRIPT

$(document).ready(function(){
    $('#anonFunction').on('keyup', function () {
        return _.debounce(debounceIt, 500, false); //Why does this differ from #function
    });
    $('#noReturnAnonFunction').on('keyup', function () {
        _.debounce(debounceIt, 500, false); //Not being executed
    });
    $('#exeDebouncedFunc').on('keyup', function () {
        _.debounce(debounceIt, 500, false)(); //Executing the debounced function results in wrong behaviour
    });
    $('#function').on('keyup', _.debounce(debounceIt, 500, false)); //This is working.
});

function debounceIt(){
    $('#output').append('debounced');
}

anonFunction そして noReturnAnonFunction はデバウンス関数を起動しませんが、最後の function は実行されます。私はこれがなぜであるか理解できません。誰かこれを理解するのを助けることができますか?

EDIT OK、では#exeDebouncedFunc (あなたが参照するもの) でデバウンスが起こらない理由は、関数が匿名関数のスコープで実行され、別のキーアップイベントが別の匿名スコープに新しい関数を作成するからです。したがって何かを入力すると何度でもデバウンスされた関数が起動します (しかし、期待通りの動作であるはずの起動は一度ではなく、次のビビア参照。 #function )?

との違いを教えてください。 #anonFunction#function . 片方が動いてもう片方が動かないのはこれまたスコープの問題なのでしょうか?

EDIT OK、それでなぜこれが起こるか理解しました。そして、なぜ私がそれを無名関数内にラップする必要があったのかがここにあります。

フィドル http://jsfiddle.net/6hg95/5/

HTML

<input id='anonFunction'/>
<div id='output'></div>

JAVASCRIPT

(function(){
    var debounce = _.debounce(fireServerEvent, 500, false);

    $('#anonFunction').on('keyup', function () {
        //clear textfield
        $('#output').append('clearNotifications<br/>');
        debounce();
    });

    function fireServerEvent(){
        $('#output').append('serverEvent<br/>');
    }
})();

どのように解決するのですか?

パルパティムが説明したように、その理由は、以下の事実にあります。 _.debounce(...) は関数を返し、それが呼び出されたときに魔法をかけるからです。

したがって、あなたの #anonFunction の例では、キーリスナーがあり、呼び出されると呼び出し元に関数を返すだけで、イベントリスナーからの戻り値には何もしません。

のスニペットです。 _.debounce(...) の定義の一部です。

_.debounce
function (func, wait, immediate) {
    var timeout;
    return function() {
      var context = this, args = arguments;
      var later = function() {
        timeout = null;
        if (!immediate) func.apply(context, args);
      };
      if (immediate && !timeout) func.apply(context, args);
      clearTimeout(timeout);
      timeout = setTimeout(later, wait);
    };
  } 

キーイベントのリスナーは _.debounce(...) あるいは、匿名でない例と同じように、返された関数を _.debounce(...) の呼び出しから返された関数をイベントリスナーとして使用することもできます。