Promise.Allのようなことをやりたいが、すべての処理が完了する前に処理を追加するとそれも含めて全てが終わるまで待ってから終了処理を実行するという動作を行うオブジェクト。
IE11で動かしたいので、jQuery.Deferredを使っている。
おそらく車輪の再発明だとは思うが、これを実現する標準的な方法が見つけられなかった。
var AddableWhen = {
_allEndProc: null,
_currentProc: null,
SetAllEndProc: function(func) {
this._allEndProc = func;
},
AddProc: function(addDeferred) {
var newProc;
if (this._currentProc == null) {
var dummyProc = $.Deferred();
dummyProc.resolve();
newProc = $.when(addDeferred, dummyProc);
} else {
this._currentProc.runThenBlock = false;
newProc = $.when(addDeferred, this._currentProc);
}
var self = this;
newProc.runThenBlock = true;
newProc.then(function(data){
if (!newProc.runThenBlock) { return; }
self._allEndProc(data);
self._currentProc = null;
});
this._currentProc = newProc;
}
};
function Test() {
var d = $.Deferred(function() {
var self = this;
log("3...");
setTimeout(function(){ log("2..."); }, 1000);
setTimeout(function(){ log("1..."); }, 2000);
setTimeout(function(){ log("0"); self.resolve(); }, 3000);
});
AddableWhen.AddProc(d);
AddableWhen.SetAllEndProc( function() { log("全部が終わりました。"); } );
}
function log(str) { // IE11にはconsole.logが無い……
document.querySelector("#log").innerHTML += str + "<br>";
}