みかづきブログ その3

3ヶ月つづけてみました。

Throttleクラスでコールバック関数の実行間隔を調整する

これまで。コールバック関数を間引きたい時は 先人につくっていただいたThrottleクラス をつかわせていただいておりましたが、良い機会なのでフルスクラッチしてみることにしてみました。


Throttleクラスに求めること

  1. インスタンスに実行間隔を渡せる
  2. インスタンスにコールバック関数も渡せる
  3. 連続して実行しても実行間隔分インターバルが開かないと発火しない
  4. 最後の1回は必ず発火する

こんな感じでしょうか。


JavaScript

(function(win, doc) {
    
    "use strict";
    
    function Throttle(opt_interval, opt_callback) {
        this._timer         = null;
        this._lastEventTime = 0;
        this._interval      = opt_interval || 500;
        this._callback      = opt_callback || function() {};
    }
    
    Throttle.prototype.setInterval = function(ms) {
        this._interval = ms;
    };
    
    Throttle.prototype.addEvent = function(fn) {
        this._callback = fn;
    };
    
    Throttle.prototype.fireEvent = function(opt_arg) {
        var that          = this,
            currentTime   = new Date() - 0,
            timerInterval = this._interval / 10;
        
        clearTimeout(that.timer);
        
        if (currentTime - that._lastEventTime > that._interval) {
            _fire();
        } else {
            that.timer = setTimeout(_fire, timerInterval);
        }
        
        function _fire() {
            that._callback.call(that, opt_arg || null);
            that._lastEventTime = currentTime;
        }
    };

})(this, document);

解説

実装方針は非常にシンプルです。必要最低限の機能しか実装していません。

インスタンスにインターバルとコールバックを1つ渡せて、
実行時に前回実行した時間と現在時刻を比較して、充分な間隔が開いていたら実行してます。
また、コールバックに渡せる引数も1つだけにしているので、複数渡したい場合は配列にいれるなどしてください。

はじめは EventDispatcher を継承して、多機能にしようと思っていたんですが、つくっているうちに複雑になってきたんでやめました。


つかいかた

インスタンスにインターバルとコールバックを渡してつかいます。
インスタンス生成時に引数として渡すこともできます。

var throttle = new Throttle();
        
throttle.setInterval(500);
throttle.addEvent(function(evt) {
    console.log(evt);
});
        
doc.addEventListener("mousemove", function(evt) {
    throttle.fireEvent(evt);
}, false);

DEMO



こんな感じになりました。
今回は以上です。