読者です 読者をやめる 読者になる 読者になる

時間差を設定し、最後にセットした関数だけを実行する

JavaScript

重たい処理があるんだけど、連続して実行したい場合にメイン処理の実行を遅延させて、最後にセットされた処理だけを実行するようなメソッドを書いてみた。例えば、コマンド入力にも使えるかも?

追記:使えそうなケース

はてなスターを連打している間はカウントだけして、連打が切れたらPOSTを行うみたいな処理がすっきり書けるはず。たぶん。

var TimeLag = function(){this.initialize();};
TimeLag.prototype ={
	initialize:function(ms){
		this.ms = ms;
		this.exe = null;
	}
	,set:function(func,obj){
		if (this.exe && !this.exe.complete) {
			this.exe.cancel();
		}
		return this.later(func,obj);
	}
	,later:function(func,thisObject) {
		var self = this;
		return function(){
			var args = arguments;
			var res = {
				complete: false,
				cancel: function(){clearTimeout(PID);},
				notify: function(){clearTimeout(PID);later_func()}
			};
			var later_func = function(){
				func.apply(thisObject,args);
				res.complete = true;
			};
			var PID = setTimeout(later_func,self.ms);
			self.exe = res;
			return res;
		}
	}
};

見てのとおり、laterは もっとエレガントにsetTimeoutをメソッド化する方法 - *「ふっかつのじゅもんがちがいます。」withぬこほぼそのまま。
こんな感じで使える。と思う。

(function(){
	var t = (new Date).getTime();
	console.log(t);
	var lag = new TimeLag(1000);
	lag.set(function(){
		console.log((new Date).getTime() - t,(new Date).getTime());
	})();
	setTimeout(function(){//上のsetはキャンセルされて、下が実行される予定になる
		lag.set(function(){
			console.log((new Date).getTime() - t,(new Date).getTime());
		})();
	},500);
	setInterval(function(){//1秒後の実行が0.5秒毎にキャンセルされて次の1秒後にセットされるので、永遠に実行されない
		lag.set(function(){
			console.log((new Date).getTime() - t,(new Date).getTime());
		})();
	},500);
})();

とりあえず書いて、これから使ってみる感じなので、色々とご了承を。ツッコミ大歓迎です。