JavaScript で遅延実行

遅延実行っていうのかな?

たとえば jQuery Interface の Sortable とかで,item を Drag'n Drop する都度 Ajax すると,サーバに負荷がかかるしモッサリしそうだし,と思いました。

なので,

  • 遅延実行してほしいメソッドを登録する
  • timeout 内に別のメソッドが追加登録された場合は,timeout を設定しなおす
  • 最終的に timeout に到達するとそこまで登録されたメソッドを実行する
    • 最後に指定されたメソッドのみ実行モード,もアリ

みたいな機能(メソッドキュー?)がほしくなって書いてみました。

var MethodQueue = function () {
    this.ctor.apply(this, arguments);
};

MethodQueue.prototype = {
    ctor:
        function () {
            if (typeof arguments[0] != 'object')
                return
                    this.ctor({
                        timeout:     arguments[0],
                        latest_only: arguments[1]
                    });

            var args = arguments[0];
            this.timeout     = args.timeout     || 1000;
            this.latest_only = args.latest_only;

            this.fns      = [];
            this.timer_id = null;
        },

    clear:
        function () {
            this.fns = [];
        },

    append:
        function (fn) {
            if (this.timer_id) {
                clearTimeout(this.timer_id);
                this.timer_id = null;
            }

            if (this.latest_only)
                this.fns = [ fn ];
            else
                this.fns[this.fns.length] = fn;

            var self = this;
            this.timer_id
                = setTimeout(function () { self._execute(); }, this.timeout);
        },

    _execute:
        function () {
            for (var i = 0; i < this.fns.length; i ++)
                this.fns[i].apply(this);

            this.clear();
        }
};

んー。すでにありそう感満点。

つか JavaScript 的にどのように書くのが smart なのかわかりません。普通どう書くんだろ。

そもそもこんなもの必要ないのかな?


使い方は,たとえば jQuery Interface Sortable だと,

var mq = new MethodQueue({
    timeout:     500,
    latest_only: true,
});

$('li.sortable_list').Sortable({
    accept: 'sortable_item',
    onStop:
        function () {
            mq.append(function () { console.log('invoked') });
        }
});

みたいに。latest_onlytrue にすると,最後に登録したメソッドのみ実行します。Ajax とかだとこういう状況のほうがアリかなぁと思いまして。