Last active
December 10, 2015 10:29
-
-
Save joseanpg/4421431 to your computer and use it in GitHub Desktop.
Dojo Deferred.js & DeferredList.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.0.3/dojo-release-1.0.3/dojo/_base/Deferred.js | |
// | |
// 02-Nov-2007 | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo._base.Deferred"); | |
dojo.require("dojo._base.lang"); | |
dojo.Deferred = function(canceller){ | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
}; | |
dojo.extend(dojo.Deferred, { | |
_nextId: (function(){ | |
var n = 1; | |
return function(){ return n++; }; | |
})(), | |
cancel: function(){ | |
var err; | |
if(this.fired == -1){ | |
if(this.canceller){ | |
err = this.canceller(this); | |
}else{ | |
this.silentlyCancelled = true; | |
} | |
if(this.fired == -1){ | |
if(!(err instanceof Error)){ | |
var res = err; | |
err = new Error("Deferred Cancelled"); | |
err.dojoType = "cancel"; | |
err.cancelResult = res; | |
} | |
this.errback(err); | |
} | |
}else if( (this.fired == 0) && | |
(this.results[0] instanceof dojo.Deferred) | |
){ | |
this.results[0].cancel(); | |
} | |
}, | |
_resback: function(res){ | |
this.fired = ((res instanceof Error) ? 1 : 0); | |
this.results[this.fired] = res; | |
this._fire(); | |
}, | |
_check: function(){ | |
if(this.fired != -1){ | |
if(!this.silentlyCancelled){ | |
throw new Error("already called!"); | |
} | |
this.silentlyCancelled = false; | |
return; | |
} | |
}, | |
callback: function(res){ | |
this._check(); | |
this._resback(res); | |
}, | |
errback: function(/*Error*/res){ | |
this._check(); | |
if(!(res instanceof Error)){ | |
res = new Error(res); | |
} | |
this._resback(res); | |
}, | |
addBoth: function( cb, cbfn ){ | |
var enclosed = dojo.hitch(cb, cbfn); | |
if(arguments.length > 2){ | |
enclosed = dojo.partial(enclosed, arguments, 2); | |
} | |
return this.addCallbacks(enclosed, enclosed); | |
}, | |
addCallback: function(cb, cbfn){ | |
var enclosed = dojo.hitch(cb, cbfn); | |
if(arguments.length > 2){ | |
enclosed = dojo.partial(enclosed, arguments, 2); | |
} | |
return this.addCallbacks(enclosed, null); | |
}, | |
addErrback: function(cb, cbfn){ | |
var enclosed = dojo.hitch(cb, cbfn); | |
if(arguments.length > 2){ | |
enclosed = dojo.partial(enclosed, arguments, 2); | |
} | |
return this.addCallbacks(null, enclosed); | |
}, | |
addCallbacks: function(cb, eb){ | |
this.chain.push([cb, eb]) | |
if(this.fired >= 0){ | |
this._fire(); | |
} | |
return this; | |
}, | |
_fire: function(){ | |
var chain = this.chain; | |
var fired = this.fired; | |
var res = this.results[fired]; | |
var self = this; | |
var cb = null; | |
while( (chain.length > 0) && (this.paused == 0) ){ | |
var f = chain.shift()[fired]; | |
if(!f){ continue; } | |
try{ | |
res = f(res); | |
fired = ((res instanceof Error) ? 1 : 0); | |
if(res instanceof dojo.Deferred){ | |
cb = function(res){ | |
self._resback(res); | |
self.paused--; | |
if( (self.paused == 0) && (self.fired >= 0) ){ | |
self._fire(); | |
} | |
} | |
this.paused++; | |
} | |
}catch(err){ | |
console.debug(err); | |
fired = 1; | |
res = err; | |
} | |
} | |
this.fired = fired; | |
this.results[fired] = res; | |
if((cb)&&(this.paused)){ | |
res.addBoth(cb); | |
} | |
} | |
}); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.0.3/dojo-release-1.0.3/dojo/DeferredList.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo.DeferredList"); | |
dojo.declare("dojo.DeferredList", dojo.Deferred, { | |
constructor: function( list, fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller){ | |
this.list = list; | |
this.resultList = new Array(this.list.length); | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
if (this.list.length === 0 && !fireOnOneCallback) { | |
this.callback(this.resultList); | |
} | |
this.finishedCount = 0; | |
this.fireOnOneCallback = fireOnOneCallback; | |
this.fireOnOneErrback = fireOnOneErrback; | |
this.consumeErrors = consumeErrors; | |
var index = 0; | |
dojo.forEach(this.list, function(d, index) { | |
d.addCallback(this, function(r) { this._cbDeferred(index, true, r); return r; }); | |
d.addErrback(this, function(r) { this._cbDeferred(index, false, r); return r; }); | |
index++; | |
},this); | |
}, | |
_cbDeferred: function (index, succeeded, result) { | |
this.resultList[index] = [succeeded, result]; this.finishedCount += 1; | |
if (this.fired !== 0) { | |
if (succeeded && this.fireOnOneCallback) { | |
this.callback([index, result]); | |
} else if (!succeeded && this.fireOnOneErrback) { | |
this.errback(result); | |
} else if (this.finishedCount == this.list.length) { | |
this.callback(this.resultList); | |
} | |
} | |
if (!succeeded && this.consumeErrors) { | |
result = null; | |
} | |
return result; | |
}, | |
gatherResults: function (deferredList) { | |
var d = new dojo.DeferedList(deferredList, false, true, false); | |
d.addCallback(function (results) { | |
var ret = []; | |
for (var i = 0; i < results.length; i++) { | |
ret.push(results[i][1]); | |
} | |
return ret; | |
}); | |
return d; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.1.2/dojo-release-1.1.2/dojo/_base/Deferred.js | |
// | |
// 03-Mar-2008 | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo._base.Deferred"); | |
dojo.require("dojo._base.lang"); | |
dojo.Deferred = function(canceller){ | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
}; | |
dojo.extend(dojo.Deferred, { | |
_nextId: (function(){ | |
var n = 1; | |
return function(){ return n++; }; | |
})(), | |
cancel: function(){ | |
var err; | |
if(this.fired == -1){ | |
if(this.canceller){ | |
err = this.canceller(this); | |
}else{ | |
this.silentlyCancelled = true; | |
} | |
if(this.fired == -1){ | |
if(!(err instanceof Error)){ | |
var res = err; | |
err = new Error("Deferred Cancelled"); | |
err.dojoType = "cancel"; | |
err.cancelResult = res; | |
} | |
this.errback(err); | |
} | |
}else if( (this.fired == 0) && | |
(this.results[0] instanceof dojo.Deferred) | |
){ | |
this.results[0].cancel(); | |
} | |
}, | |
_resback: function(res){ | |
this.fired = ((res instanceof Error) ? 1 : 0); | |
this.results[this.fired] = res; | |
this._fire(); | |
}, | |
_check: function(){ | |
if(this.fired != -1){ | |
if(!this.silentlyCancelled){ | |
throw new Error("already called!"); | |
} | |
this.silentlyCancelled = false; | |
return; | |
} | |
}, | |
callback: function(res){ | |
this._check(); | |
this._resback(res); | |
}, | |
errback: function(/*Error*/res){ | |
this._check(); | |
if(!(res instanceof Error)){ | |
res = new Error(res); | |
} | |
this._resback(res); | |
}, | |
addBoth: function( cb, cbfn ){ //New version | |
var enclosed = dojo.hitch.apply(dojo, arguments); | |
return this.addCallbacks(enclosed, enclosed); | |
}, | |
addCallback: function( cb, cbfn ){ //New version | |
return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); | |
}, | |
addErrback: function(cb, cbfn){ //New version | |
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); | |
}, | |
addCallbacks: function(cb, eb){ | |
this.chain.push([cb, eb]) | |
if(this.fired >= 0){ | |
this._fire(); | |
} | |
return this; | |
}, | |
_fire: function(){ | |
var chain = this.chain; | |
var fired = this.fired; | |
var res = this.results[fired]; | |
var self = this; | |
var cb = null; | |
while( (chain.length > 0) && (this.paused == 0) ){ | |
var f = chain.shift()[fired]; | |
if(!f){ continue; } | |
try{ | |
res = f(res); | |
fired = ((res instanceof Error) ? 1 : 0); | |
if(res instanceof dojo.Deferred){ | |
cb = function(res){ | |
self._resback(res); | |
self.paused--; | |
if( (self.paused == 0) && (self.fired >= 0) ){ | |
self._fire(); | |
} | |
} | |
this.paused++; | |
} | |
}catch(err){ | |
console.debug(err); | |
fired = 1; | |
res = err; | |
} | |
} | |
this.fired = fired; | |
this.results[fired] = res; | |
if((cb)&&(this.paused)){ | |
res.addBoth(cb); | |
} | |
} | |
}); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.1.2/dojo-release-1.1.2/dojo/DeferredList.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo.DeferredList"); | |
dojo.declare("dojo.DeferredList", dojo.Deferred, { | |
constructor: function( list, fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller){ | |
this.list = list; | |
this.resultList = new Array(this.list.length); | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
if(this.list.length === 0 && !fireOnOneCallback){ | |
this.callback(this.resultList); | |
} | |
this.finishedCount = 0; | |
this.fireOnOneCallback = fireOnOneCallback; | |
this.fireOnOneErrback = fireOnOneErrback; | |
this.consumeErrors = consumeErrors; | |
dojo.forEach(this.list, function(d, index){ | |
d.addCallback(this, function(r){ this._cbDeferred(index, true, r); return r; }); | |
d.addErrback(this, function(r){ this._cbDeferred(index, false, r); return r; }); | |
}, this); | |
}, | |
_cbDeferred: function(index, succeeded, result){ | |
this.resultList[index] = [succeeded, result]; this.finishedCount += 1; | |
if(this.fired !== 0){ | |
if(succeeded && this.fireOnOneCallback){ | |
this.callback([index, result]); | |
}else if(!succeeded && this.fireOnOneErrback){ | |
this.errback(result); | |
}else if(this.finishedCount == this.list.length){ | |
this.callback(this.resultList); | |
} | |
} | |
if(!succeeded && this.consumeErrors){ | |
result = null; | |
} | |
return result; | |
}, | |
gatherResults: function(deferredList){ | |
var d = new dojo.DeferredList(deferredList, false, true, false); | |
d.addCallback(function(results){ | |
var ret = []; | |
dojo.forEach(results, function(result){ | |
ret.push(result[1]); | |
}); | |
return ret; | |
}); | |
return d; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.2.4/dojo-release-1.2.4/dojo/_base/Deferred.js | |
// | |
// 16-Aug-2008 | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo._base.Deferred"); | |
dojo.require("dojo._base.lang"); | |
dojo.Deferred = function(canceller){ | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
}; | |
dojo.extend(dojo.Deferred, { | |
_nextId: (function(){ | |
var n = 1; | |
return function(){ return n++; }; | |
})(), | |
cancel: function(){ | |
var err; | |
if(this.fired == -1){ | |
if(this.canceller){ | |
err = this.canceller(this); | |
}else{ | |
this.silentlyCancelled = true; | |
} | |
if(this.fired == -1){ | |
if(!(err instanceof Error)){ | |
var res = err; | |
err = new Error("Deferred Cancelled"); | |
err.dojoType = "cancel"; | |
err.cancelResult = res; | |
} | |
this.errback(err); | |
} | |
}else if( (this.fired == 0) && | |
(this.results[0] instanceof dojo.Deferred) | |
){ | |
this.results[0].cancel(); | |
} | |
}, | |
_resback: function(res){ | |
// summary: | |
// The private primitive that means either callback or errback | |
this.fired = ((res instanceof Error) ? 1 : 0); | |
this.results[this.fired] = res; | |
this._fire(); | |
}, | |
_check: function(){ | |
if(this.fired != -1){ | |
if(!this.silentlyCancelled){ | |
throw new Error("already called!"); | |
} | |
this.silentlyCancelled = false; | |
return; | |
} | |
}, | |
callback: function(res){ | |
this._check(); | |
this._resback(res); | |
}, | |
errback: function(res){ | |
this._check(); | |
if(!(res instanceof Error)){ | |
res = new Error(res); | |
} | |
this._resback(res); | |
}, | |
addBoth: function( cb, cbfn){ | |
var enclosed = dojo.hitch.apply(dojo, arguments); | |
return this.addCallbacks(enclosed, enclosed); // dojo.Deferred | |
}, | |
addCallback: function( cb, cbfn ){ | |
return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addErrback: function(cb, cbfn){ | |
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addCallbacks: function(cb, eb){ | |
this.chain.push([cb, eb]) | |
if(this.fired >= 0){ | |
this._fire(); | |
} | |
return this; // dojo.Deferred | |
}, | |
_fire: function(){ | |
var chain = this.chain; | |
var fired = this.fired; | |
var res = this.results[fired]; | |
var self = this; | |
var cb = null; | |
while( (chain.length > 0) && (this.paused == 0) ){ | |
var f = chain.shift()[fired]; | |
if(!f){ continue; } | |
var func = function(){ | |
var ret = f(res); | |
if(typeof ret != "undefined"){ | |
res = ret; | |
} | |
fired = ((res instanceof Error) ? 1 : 0); | |
if(res instanceof dojo.Deferred){ | |
cb = function(res){ | |
self._resback(res); | |
self.paused--; | |
if( | |
(self.paused == 0) && | |
(self.fired >= 0) | |
){ | |
self._fire(); | |
} | |
} | |
this.paused++; | |
} | |
}; | |
if(dojo.config.isDebug){ | |
func.call(this); | |
}else{ | |
try{ | |
func.call(this); | |
}catch(err){ | |
fired = 1; | |
res = err; | |
} | |
} | |
} | |
this.fired = fired; | |
this.results[fired] = res; | |
if((cb)&&(this.paused)){ | |
res.addBoth(cb); | |
} | |
} | |
}); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.2.4/dojo-release-1.2.4/dojo/DeferredList.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo.DeferredList"); | |
dojo.declare("dojo.DeferredList", dojo.Deferred, { | |
constructor: function( list, fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller){ | |
this.list = list; | |
this.resultList = new Array(this.list.length); | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
if(this.list.length === 0 && !fireOnOneCallback){ | |
this.callback(this.resultList); | |
} | |
this.finishedCount = 0; | |
this.fireOnOneCallback = fireOnOneCallback; | |
this.fireOnOneErrback = fireOnOneErrback; | |
this.consumeErrors = consumeErrors; | |
dojo.forEach(this.list, function(d, index){ | |
d.addCallback(this, function(r){ this._cbDeferred(index, true, r); return r; }); | |
d.addErrback(this, function(r){ this._cbDeferred(index, false, r); return r; }); | |
}, this); | |
}, | |
_cbDeferred: function(index, succeeded, result){ | |
this.resultList[index] = [succeeded, result]; this.finishedCount += 1; | |
if(this.fired !== 0){ | |
if(succeeded && this.fireOnOneCallback){ | |
this.callback([index, result]); | |
}else if(!succeeded && this.fireOnOneErrback){ | |
this.errback(result); | |
}else if(this.finishedCount == this.list.length){ | |
this.callback(this.resultList); | |
} | |
} | |
if(!succeeded && this.consumeErrors){ | |
result = null; | |
} | |
return result; | |
}, | |
gatherResults: function(deferredList){ | |
var d = new dojo.DeferredList(deferredList, false, true, false); | |
d.addCallback(function(results){ | |
var ret = []; | |
dojo.forEach(results, function(result){ | |
ret.push(result[1]); | |
}); | |
return ret; | |
}); | |
return d; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.3.3/dojo-release-1.3.3/dojo/_base/Deferred.js | |
// | |
// 10-Dec-2008 | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo._base.Deferred"); | |
dojo.require("dojo._base.lang"); | |
dojo.Deferred = function(canceller){ | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
}; | |
dojo.extend(dojo.Deferred, { | |
_nextId: (function(){ | |
var n = 1; | |
return function(){ return n++; }; | |
})(), | |
cancel: function(){ | |
var err; | |
if(this.fired == -1){ | |
if(this.canceller){ | |
err = this.canceller(this); | |
}else{ | |
this.silentlyCancelled = true; | |
} | |
if(this.fired == -1){ | |
if(!(err instanceof Error)){ | |
var res = err; | |
var msg = "Deferred Cancelled"; | |
if(err && err.toString){ | |
msg += ": " + err.toString(); | |
} | |
err = new Error(msg); | |
err.dojoType = "cancel"; | |
err.cancelResult = res; | |
} | |
this.errback(err); | |
} | |
}else if( (this.fired == 0) && | |
(this.results[0] instanceof dojo.Deferred) | |
){ | |
this.results[0].cancel(); | |
} | |
}, | |
_resback: function(res){ | |
this.fired = ((res instanceof Error) ? 1 : 0); | |
this.results[this.fired] = res; | |
this._fire(); | |
}, | |
_check: function(){ | |
if(this.fired != -1){ | |
if(!this.silentlyCancelled){ | |
throw new Error("already called!"); | |
} | |
this.silentlyCancelled = false; | |
return; | |
} | |
}, | |
callback: function(res){ | |
this._check(); | |
this._resback(res); | |
}, | |
errback: function(/*Error*/res){ | |
this._check(); | |
if(!(res instanceof Error)){ | |
res = new Error(res); | |
} | |
this._resback(res); | |
}, | |
addBoth: function( cb, cbfn){ | |
var enclosed = dojo.hitch.apply(dojo, arguments); | |
return this.addCallbacks(enclosed, enclosed); // dojo.Deferred | |
}, | |
addCallback: function( cb, cbfn ){ | |
return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addErrback: function(cb, cbfn){ | |
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addCallbacks: function(cb, eb){ | |
this.chain.push([cb, eb]) | |
if(this.fired >= 0){ | |
this._fire(); | |
} | |
return this; // dojo.Deferred | |
}, | |
_fire: function(){ | |
var chain = this.chain; | |
var fired = this.fired; | |
var res = this.results[fired]; | |
var self = this; | |
var cb = null; | |
while( (chain.length > 0) && (this.paused == 0) ){ | |
var f = chain.shift()[fired]; | |
if(!f){ continue; } | |
var func = function(){ | |
var ret = f(res); | |
if(typeof ret != "undefined"){ | |
res = ret; | |
} | |
fired = ((res instanceof Error) ? 1 : 0); | |
if(res instanceof dojo.Deferred){ | |
cb = function(res){ | |
self._resback(res); | |
self.paused--; | |
if( (self.paused == 0) && (self.fired >= 0) ){ | |
self._fire(); | |
} | |
} | |
this.paused++; | |
} | |
}; | |
if(dojo.config.debugAtAllCosts){ | |
func.call(this); | |
}else{ | |
try{ | |
func.call(this); | |
}catch(err){ | |
fired = 1; | |
res = err; | |
} | |
} | |
} | |
this.fired = fired; | |
this.results[fired] = res; | |
if((cb)&&(this.paused)){ | |
res.addBoth(cb); | |
} | |
} | |
}); | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.3.3/dojo-release-1.3.3/dojo/DeferredList.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
dojo.provide("dojo.DeferredList"); | |
dojo.declare("dojo.DeferredList", dojo.Deferred, { | |
constructor: function( list, fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller){ | |
this.list = list; | |
this.resultList = new Array(this.list.length); | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
if(this.list.length === 0 && !fireOnOneCallback){ | |
this.callback(this.resultList); | |
} | |
this.finishedCount = 0; | |
this.fireOnOneCallback = fireOnOneCallback; | |
this.fireOnOneErrback = fireOnOneErrback; | |
this.consumeErrors = consumeErrors; | |
dojo.forEach(this.list, function(d, index){ | |
d.addCallback(this, function(r){ this._cbDeferred(index, true, r); return r; }); | |
d.addErrback(this, function(r){ this._cbDeferred(index, false, r); return r; }); | |
}, this); | |
}, | |
_cbDeferred: function(index, succeeded, result){ | |
this.resultList[index] = [succeeded, result]; this.finishedCount += 1; | |
if(this.fired !== 0){ | |
if(succeeded && this.fireOnOneCallback){ | |
this.callback([index, result]); | |
}else if(!succeeded && this.fireOnOneErrback){ | |
this.errback(result); | |
}else if(this.finishedCount == this.list.length){ | |
this.callback(this.resultList); | |
} | |
} | |
if(!succeeded && this.consumeErrors){ | |
result = null; | |
} | |
return result; | |
}, | |
gatherResults: function(deferredList){ | |
var d = new dojo.DeferredList(deferredList, false, true, false); | |
d.addCallback(function(results){ | |
var ret = []; | |
dojo.forEach(results, function(result){ | |
ret.push(result[1]); | |
}); | |
return ret; | |
}); | |
return d; | |
} | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.4.4/dojo-release-1.4.4/dojo/_base/Deferred.js | |
// | |
// 2009 | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////// | |
if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. | |
dojo._hasResource["dojo._base.Deferred"] = true; | |
dojo.provide("dojo._base.Deferred"); | |
dojo.require("dojo._base.lang"); | |
dojo.Deferred = function(canceller){ | |
this.chain = []; | |
this.id = this._nextId(); | |
this.fired = -1; | |
this.paused = 0; | |
this.results = [null, null]; | |
this.canceller = canceller; | |
this.silentlyCancelled = false; | |
this.isFiring = false; | |
}; | |
dojo.extend(dojo.Deferred, { | |
_nextId: (function(){ | |
var n = 1; | |
return function(){ return n++; }; | |
})(), | |
cancel: function(){ | |
var err; | |
if(this.fired == -1){ | |
if(this.canceller){ | |
err = this.canceller(this); | |
}else{ | |
this.silentlyCancelled = true; | |
} | |
if(this.fired == -1){ | |
if(!(err instanceof Error)){ | |
var res = err; | |
var msg = "Deferred Cancelled"; | |
if(err && err.toString){ | |
msg += ": " + err.toString(); | |
} | |
err = new Error(msg); | |
err.dojoType = "cancel"; | |
err.cancelResult = res; | |
} | |
this.errback(err); | |
} | |
}else if( (this.fired == 0) && | |
(this.results[0] instanceof dojo.Deferred) | |
){ | |
this.results[0].cancel(); | |
} | |
}, | |
_resback: function(res){ | |
this.fired = ((res instanceof Error) ? 1 : 0); | |
this.results[this.fired] = res; | |
this._fire(); | |
}, | |
_check: function(){ | |
if(this.fired != -1){ | |
if(!this.silentlyCancelled){ | |
throw new Error("already called!"); | |
} | |
this.silentlyCancelled = false; | |
return; | |
} | |
}, | |
callback: function(res){ | |
this._check(); | |
this._resback(res); | |
}, | |
errback: function(res){ | |
this._check(); | |
if(!(res instanceof Error)){ | |
res = new Error(res); | |
} | |
this._resback(res); | |
}, | |
addBoth: function( cb, cbfn){ | |
var enclosed = dojo.hitch.apply(dojo, arguments); | |
return this.addCallbacks(enclosed, enclosed); // dojo.Deferred | |
}, | |
addCallback: function( cb, cbfn ){ | |
return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addErrback: function(cb, cbfn){ | |
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addCallbacks: function(cb, eb){ | |
this.chain.push([cb, eb]) | |
if(this.fired >= 0 && !this.isFiring){ | |
this._fire(); | |
} | |
return this; // dojo.Deferred | |
}, | |
_fire: function(){ | |
this.isFiring = true; | |
var chain = this.chain; | |
var fired = this.fired; | |
var res = this.results[fired]; | |
var self = this; | |
var cb = null; | |
while( (chain.length > 0) && (this.paused == 0) ){ | |
var f = chain.shift()[fired]; | |
if(!f){ contin |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.5.2/dojo-release-1.5.2/dojo/_base/Deferred.js | |
// | |
// 2010 | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. | |
Available via Academic Free License >= 2.1 OR the modified BSD license. | |
see: http://dojotoolkit.org/license for details | |
*/ | |
if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. | |
dojo._hasResource["dojo._base.Deferred"] = true; | |
dojo.provide("dojo._base.Deferred"); | |
dojo.require("dojo._base.lang"); | |
(function(){ | |
var mutator = function(){}; | |
var freeze = Object.freeze || function(){}; | |
// A deferred provides an API for creating and resolving a promise. | |
dojo.Deferred = function(/*Function?*/canceller){ | |
// summary: | |
// Deferreds provide a generic means for encapsulating an asynchronous | |
// operation and notifying users of the completion and result of the operation. | |
// description: | |
// The dojo.Deferred API is based on the concept of promises that provide a | |
// generic interface into the eventual completion of an asynchronous action. | |
// The motivation for promises fundamentally is about creating a | |
// separation of concerns that allows one to achieve the same type of | |
// call patterns and logical data flow in asynchronous code as can be | |
// achieved in synchronous code. Promises allows one | |
// to be able to call a function purely with arguments needed for | |
// execution, without conflating the call with concerns of whether it is | |
// sync or async. One shouldn't need to alter a call's arguments if the | |
// implementation switches from sync to async (or vice versa). By having | |
// async functions return promises, the concerns of making the call are | |
// separated from the concerns of asynchronous interaction (which are | |
// handled by the promise). | |
// | |
// The dojo.Deferred is a type of promise that provides methods for fulfilling the | |
// promise with a successful result or an error. The most important method for | |
// working with Dojo's promises is the then() method, which follows the | |
// CommonJS proposed promise API. An example of using a Dojo promise: | |
// | |
// | var resultingPromise = someAsyncOperation.then(function(result){ | |
// | ... handle result ... | |
// | }, | |
// | function(error){ | |
// | ... handle error ... | |
// | }); | |
// | |
// The .then() call returns a new promise that represents the result of the | |
// execution of the callback. The callbacks will never affect the original promises value. | |
// | |
// The dojo.Deferred instances also provide the following functions for backwards compatibility: | |
// | |
// * addCallback(handler) | |
// * addErrback(handler) | |
// * callback(result) | |
// * errback(result) | |
// | |
// Callbacks are allowed to return promisesthemselves, so | |
// you can build complicated sequences of events with ease. | |
// | |
// The creator of the Deferred may specify a canceller. The canceller | |
// is a function that will be called if Deferred.cancel is called | |
// before the Deferred fires. You can use this to implement clean | |
// aborting of an XMLHttpRequest, etc. Note that cancel will fire the | |
// deferred with a CancelledError (unless your canceller returns | |
// another kind of error), so the errbacks should be prepared to | |
// handle that error for cancellable Deferreds. | |
// example: | |
// | var deferred = new dojo.Deferred(); | |
// | setTimeout(function(){ deferred.callback({success: true}); }, 1000); | |
// | return deferred; | |
// example: | |
// Deferred objects are often used when making code asynchronous. It | |
// may be easiest to write functions in a synchronous manner and then | |
// split code using a deferred to trigger a response to a long-lived | |
// operation. For example, instead of register a callback function to | |
// denote when a rendering operation completes, the function can | |
// simply return a deferred: | |
// | |
// | // callback style: | |
// | function renderLotsOfData(data, callback){ | |
// | var success = false | |
// | try{ | |
// | for(var x in data){ | |
// | renderDataitem(data[x]); | |
// | } | |
// | success = true; | |
// | }catch(e){ } | |
// | if(callback){ | |
// | callback(success); | |
// | } | |
// | } | |
// | |
// | // using callback style | |
// | renderLotsOfData(someDataObj, function(success){ | |
// | // handles success or failure | |
// | if(!success){ | |
// | promptUserToRecover(); | |
// | } | |
// | }); | |
// | // NOTE: no way to add another callback here!! | |
// example: | |
// Using a Deferred doesn't simplify the sending code any, but it | |
// provides a standard interface for callers and senders alike, | |
// providing both with a simple way to service multiple callbacks for | |
// an operation and freeing both sides from worrying about details | |
// such as "did this get called already?". With Deferreds, new | |
// callbacks can be added at any time. | |
// | |
// | // Deferred style: | |
// | function renderLotsOfData(data){ | |
// | var d = new dojo.Deferred(); | |
// | try{ | |
// | for(var x in data){ | |
// | renderDataitem(data[x]); | |
// | } | |
// | d.callback(true); | |
// | }catch(e){ | |
// | d.errback(new Error("rendering failed")); | |
// | } | |
// | return d; | |
// | } | |
// | |
// | // using Deferred style | |
// | renderLotsOfData(someDataObj).then(null, function(){ | |
// | promptUserToRecover(); | |
// | }); | |
// | // NOTE: addErrback and addCallback both return the Deferred | |
// | // again, so we could chain adding callbacks or save the | |
// | // deferred for later should we need to be notified again. | |
// example: | |
// In this example, renderLotsOfData is syncrhonous and so both | |
// versions are pretty artificial. Putting the data display on a | |
// timeout helps show why Deferreds rock: | |
// | |
// | // Deferred style and async func | |
// | function renderLotsOfData(data){ | |
// | var d = new dojo.Deferred(); | |
// | setTimeout(function(){ | |
// | try{ | |
// | for(var x in data){ | |
// | renderDataitem(data[x]); | |
// | } | |
// | d.callback(true); | |
// | }catch(e){ | |
// | d.errback(new Error("rendering failed")); | |
// | } | |
// | }, 100); | |
// | return d; | |
// | } | |
// | |
// | // using Deferred style | |
// | renderLotsOfData(someDataObj).then(null, function(){ | |
// | promptUserToRecover(); | |
// | }); | |
// | |
// Note that the caller doesn't have to change his code at all to | |
// handle the asynchronous case. | |
var result, finished, isError, head, nextListener; | |
var promise = this.promise = {}; | |
function complete(value){ | |
if(finished){ | |
throw new Error("This deferred has already been resolved"); | |
} | |
result = value; | |
finished = true; | |
notify(); | |
} | |
function notify(){ | |
var mutated; | |
while(!mutated && nextListener){ | |
var listener = nextListener; | |
nextListener = nextListener.next; | |
if(mutated = (listener.progress == mutator)){ // assignment and check | |
finished = false; | |
} | |
var func = (isError ? listener.error : listener.resolved); | |
if (func) { | |
try { | |
var newResult = func(result); | |
if (newResult && typeof newResult.then === "function") { | |
newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject")); | |
continue; | |
} | |
var unchanged = mutated && newResult === undefined; | |
listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult); | |
} | |
catch (e) { | |
listener.deferred.reject(e); | |
} | |
}else { | |
if(isError){ | |
listener.deferred.reject(result); | |
}else{ | |
listener.deferred.resolve(result); | |
} | |
} | |
} | |
} | |
// calling resolve will resolve the promise | |
this.resolve = this.callback = function(value){ | |
// summary: | |
// Fulfills the Deferred instance successfully with the provide value | |
this.fired = 0; | |
this.results = [value, null]; | |
complete(value); | |
}; | |
// calling error will indicate that the promise failed | |
this.reject = this.errback = function(error){ | |
// summary: | |
// Fulfills the Deferred instance as an error with the provided error | |
isError = true; | |
this.fired = 1; | |
complete(error); | |
this.results = [null, error]; | |
if(!error || error.log !== false){ | |
(dojo.config.deferredOnError || function(x){ console.error(x); })(error); | |
} | |
}; | |
// call progress to provide updates on the progress on the completion of the promise | |
this.progress = function(update){ | |
// summary | |
// Send progress events to all listeners | |
var listener = nextListener; | |
while(listener){ | |
var progress = listener.progress; | |
progress && progress(update); | |
listener = listener.next; | |
} | |
}; | |
this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){ | |
this.then(callback, errback, mutator); | |
return this; | |
}; | |
// provide the implementation of the promise | |
this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){ | |
// summary | |
// Adds a fulfilledHandler, errorHandler, and progressHandler to be called for | |
// completion of a promise. The fulfilledHandler is called when the promise | |
// is fulfilled. The errorHandler is called when a promise fails. The | |
// progressHandler is called for progress events. All arguments are optional | |
// and non-function values are ignored. The progressHandler is not only an | |
// optional argument, but progress events are purely optional. Promise | |
// providers are not required to ever create progress events. | |
// | |
// This function will return a new promise that is fulfilled when the given | |
// fulfilledHandler or errorHandler callback is finished. This allows promise | |
// operations to be chained together. The value returned from the callback | |
// handler is the fulfillment value for the returned promise. If the callback | |
// throws an error, the returned promise will be moved to failed state. | |
// | |
// example: | |
// An example of using a CommonJS compliant promise: | |
// | asyncComputeTheAnswerToEverything(). | |
// | then(addTwo). | |
// | then(printResult, onError); | |
// | >44 | |
// | |
var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel); | |
var listener = { | |
resolved: resolvedCallback, | |
error: errorCallback, | |
progress: progressCallback, | |
deferred: returnDeferred | |
}; | |
if(nextListener){ | |
head = head.next = listener; | |
} | |
else{ | |
nextListener = head = listener; | |
} | |
if(finished){ | |
notify(); | |
} | |
return returnDeferred.promise; | |
}; | |
var deferred = this; | |
this.cancel = promise.cancel = function () { | |
// summary: | |
// Cancels the asynchronous operation | |
if(!finished){ | |
var error = canceller && canceller(deferred); | |
if(!finished){ | |
if (!(error instanceof Error)) { | |
error = new Error(error); | |
} | |
error.log = false; | |
deferred.reject(error); | |
} | |
} | |
} | |
freeze(promise); | |
}; | |
dojo.extend(dojo.Deferred, { | |
addCallback: function (/*Function*/callback) { | |
return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); | |
}, | |
addErrback: function (/*Function*/errback) { | |
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); | |
}, | |
addBoth: function (/*Function*/callback) { | |
var enclosed = dojo.hitch.apply(dojo, arguments); | |
return this.addCallbacks(enclosed, enclosed); | |
}, | |
fired: -1 | |
}); | |
})(); | |
dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){ | |
// summary: | |
// This provides normalization between normal synchronous values and | |
// asynchronous promises, so you can interact with them in a common way | |
// example: | |
// | function printFirstAndList(items){ | |
// | dojo.when(findFirst(items), console.log); | |
// | dojo.when(findLast(items), console.log); | |
// | } | |
// | function findFirst(items){ | |
// | return dojo.when(items, function(items){ | |
// | return items[0]; | |
// | }); | |
// | } | |
// | function findLast(items){ | |
// | return dojo.when(items, function(items){ | |
// | return items[items.length]; | |
// | }); | |
// | } | |
// And now all three of his functions can be used sync or async. | |
// | printFirstAndLast([1,2,3,4]) will work just as well as | |
// | printFirstAndLast(dojo.xhrGet(...)); | |
if(promiseOrValue && typeof promiseOrValue.then === "function"){ | |
return promiseOrValue.then(callback, errback, progressHandler); | |
} | |
return callback(promiseOrValue); | |
}; | |
} | |
////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.5.2/dojo-release-1.5.2/dojo/DeferredList.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Copyright (c) 2004-2010, The Dojo Foundation All Rights Reserved. | |
Available via Academic Free License >= 2.1 OR the modified BSD license. | |
see: http://dojotoolkit.org/license for details | |
*/ | |
if(!dojo._hasResource["dojo.DeferredList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. | |
dojo._hasResource["dojo.DeferredList"] = true; | |
dojo.provide("dojo.DeferredList"); | |
dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*Boolean?*/ fireOnOneErrback, /*Boolean?*/ consumeErrors, /*Function?*/ canceller){ | |
// summary: | |
// Provides event handling for a group of Deferred objects. | |
// description: | |
// DeferredList takes an array of existing deferreds and returns a new deferred of its own | |
// this new deferred will typically have its callback fired when all of the deferreds in | |
// the given list have fired their own deferreds. The parameters `fireOnOneCallback` and | |
// fireOnOneErrback, will fire before all the deferreds as appropriate | |
// | |
// list: | |
// The list of deferreds to be synchronizied with this DeferredList | |
// fireOnOneCallback: | |
// Will cause the DeferredLists callback to be fired as soon as any | |
// of the deferreds in its list have been fired instead of waiting until | |
// the entire list has finished | |
// fireonOneErrback: | |
// Will cause the errback to fire upon any of the deferreds errback | |
// canceller: | |
// A deferred canceller function, see dojo.Deferred | |
var resultList = []; | |
dojo.Deferred.call(this); | |
var self = this; | |
if(list.length === 0 && !fireOnOneCallback){ | |
this.resolve([0, []]); | |
} | |
var finished = 0; | |
dojo.forEach(list, function(item, i){ | |
item.then(function(result){ | |
if(fireOnOneCallback){ | |
self.resolve([i, result]); | |
}else{ | |
addResult(true, result); | |
} | |
},function(error){ | |
if(fireOnOneErrback){ | |
self.reject(error); | |
}else{ | |
addResult(false, error); | |
} | |
if(consumeErrors){ | |
return null; | |
} | |
throw error; | |
}); | |
function addResult(succeeded, result){ | |
resultList[i] = [succeeded, result]; | |
finished++; | |
if(finished === list.length){ | |
self.resolve(resultList); | |
} | |
} | |
}); | |
}; | |
dojo.DeferredList.prototype = new dojo.Deferred(); | |
dojo.DeferredList.prototype.gatherResults= function(deferredList){ | |
// summary: | |
// Gathers the results of the deferreds for packaging | |
// as the parameters to the Deferred Lists' callback | |
var d = new dojo.DeferredList(deferredList, false, true, false); | |
d.addCallback(function(results){ | |
var ret = []; | |
dojo.forEach(results, function(result){ | |
ret.push(result[1]); | |
}); | |
return ret; | |
}); | |
return d; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.6.1/dojo-release-1.6.1/dojo/_base/Deferred.js | |
// | |
// 2011 | |
// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. | |
Available via Academic Free License >= 2.1 OR the modified BSD license. | |
see: http://dojotoolkit.org/license for details | |
*/ | |
if(!dojo._hasResource["dojo._base.Deferred"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. | |
dojo._hasResource["dojo._base.Deferred"] = true; | |
dojo.provide("dojo._base.Deferred"); | |
dojo.require("dojo._base.lang"); | |
(function(){ | |
var mutator = function(){}; | |
var freeze = Object.freeze || function(){}; | |
// A deferred provides an API for creating and resolving a promise. | |
dojo.Deferred = function(/*Function?*/canceller){ | |
// summary: | |
// Deferreds provide a generic means for encapsulating an asynchronous | |
// operation and notifying users of the completion and result of the operation. | |
// description: | |
// The dojo.Deferred API is based on the concept of promises that provide a | |
// generic interface into the eventual completion of an asynchronous action. | |
// The motivation for promises fundamentally is about creating a | |
// separation of concerns that allows one to achieve the same type of | |
// call patterns and logical data flow in asynchronous code as can be | |
// achieved in synchronous code. Promises allows one | |
// to be able to call a function purely with arguments needed for | |
// execution, without conflating the call with concerns of whether it is | |
// sync or async. One shouldn't need to alter a call's arguments if the | |
// implementation switches from sync to async (or vice versa). By having | |
// async functions return promises, the concerns of making the call are | |
// separated from the concerns of asynchronous interaction (which are | |
// handled by the promise). | |
// | |
// The dojo.Deferred is a type of promise that provides methods for fulfilling the | |
// promise with a successful result or an error. The most important method for | |
// working with Dojo's promises is the then() method, which follows the | |
// CommonJS proposed promise API. An example of using a Dojo promise: | |
// | |
// | var resultingPromise = someAsyncOperation.then(function(result){ | |
// | ... handle result ... | |
// | }, | |
// | function(error){ | |
// | ... handle error ... | |
// | }); | |
// | |
// The .then() call returns a new promise that represents the result of the | |
// execution of the callback. The callbacks will never affect the original promises value. | |
// | |
// The dojo.Deferred instances also provide the following functions for backwards compatibility: | |
// | |
// * addCallback(handler) | |
// * addErrback(handler) | |
// * callback(result) | |
// * errback(result) | |
// | |
// Callbacks are allowed to return promises themselves, so | |
// you can build complicated sequences of events with ease. | |
// | |
// The creator of the Deferred may specify a canceller. The canceller | |
// is a function that will be called if Deferred.cancel is called | |
// before the Deferred fires. You can use this to implement clean | |
// aborting of an XMLHttpRequest, etc. Note that cancel will fire the | |
// deferred with a CancelledError (unless your canceller returns | |
// another kind of error), so the errbacks should be prepared to | |
// handle that error for cancellable Deferreds. | |
// example: | |
// | var deferred = new dojo.Deferred(); | |
// | setTimeout(function(){ deferred.callback({success: true}); }, 1000); | |
// | return deferred; | |
// example: | |
// Deferred objects are often used when making code asynchronous. It | |
// may be easiest to write functions in a synchronous manner and then | |
// split code using a deferred to trigger a response to a long-lived | |
// operation. For example, instead of register a callback function to | |
// denote when a rendering operation completes, the function can | |
// simply return a deferred: | |
// | |
// | // callback style: | |
// | function renderLotsOfData(data, callback){ | |
// | var success = false | |
// | try{ | |
// | for(var x in data){ | |
// | renderDataitem(data[x]); | |
// | } | |
// | success = true; | |
// | }catch(e){ } | |
// | if(callback){ | |
// | callback(success); | |
// | } | |
// | } | |
// | |
// | // using callback style | |
// | renderLotsOfData(someDataObj, function(success){ | |
// | // handles success or failure | |
// | if(!success){ | |
// | promptUserToRecover(); | |
// | } | |
// | }); | |
// | // NOTE: no way to add another callback here!! | |
// example: | |
// Using a Deferred doesn't simplify the sending code any, but it | |
// provides a standard interface for callers and senders alike, | |
// providing both with a simple way to service multiple callbacks for | |
// an operation and freeing both sides from worrying about details | |
// such as "did this get called already?". With Deferreds, new | |
// callbacks can be added at any time. | |
// | |
// | // Deferred style: | |
// | function renderLotsOfData(data){ | |
// | var d = new dojo.Deferred(); | |
// | try{ | |
// | for(var x in data){ | |
// | renderDataitem(data[x]); | |
// | } | |
// | d.callback(true); | |
// | }catch(e){ | |
// | d.errback(new Error("rendering failed")); | |
// | } | |
// | return d; | |
// | } | |
// | |
// | // using Deferred style | |
// | renderLotsOfData(someDataObj).then(null, function(){ | |
// | promptUserToRecover(); | |
// | }); | |
// | // NOTE: addErrback and addCallback both return the Deferred | |
// | // again, so we could chain adding callbacks or save the | |
// | // deferred for later should we need to be notified again. | |
// example: | |
// In this example, renderLotsOfData is synchronous and so both | |
// versions are pretty artificial. Putting the data display on a | |
// timeout helps show why Deferreds rock: | |
// | |
// | // Deferred style and async func | |
// | function renderLotsOfData(data){ | |
// | var d = new dojo.Deferred(); | |
// | setTimeout(function(){ | |
// | try{ | |
// | for(var x in data){ | |
// | renderDataitem(data[x]); | |
// | } | |
// | d.callback(true); | |
// | }catch(e){ | |
// | d.errback(new Error("rendering failed")); | |
// | } | |
// | }, 100); | |
// | return d; | |
// | } | |
// | |
// | // using Deferred style | |
// | renderLotsOfData(someDataObj).then(null, function(){ | |
// | promptUserToRecover(); | |
// | }); | |
// | |
// Note that the caller doesn't have to change his code at all to | |
// handle the asynchronous case. | |
var result, finished, isError, head, nextListener; | |
var promise = (this.promise = {}); | |
function complete(value){ | |
if(finished){ | |
throw new Error("This deferred has already been resolved"); | |
} | |
result = value; | |
finished = true; | |
notify(); | |
} | |
function notify(){ | |
var mutated; | |
while(!mutated && nextListener){ | |
var listener = nextListener; | |
nextListener = nextListener.next; | |
if((mutated = (listener.progress == mutator))){ // assignment and check | |
finished = false; | |
} | |
var func = (isError ? listener.error : listener.resolved); | |
if (func) { | |
try { | |
var newResult = func(result); | |
if (newResult && typeof newResult.then === "function") { | |
newResult.then(dojo.hitch(listener.deferred, "resolve"), dojo.hitch(listener.deferred, "reject")); | |
continue; | |
} | |
var unchanged = mutated && newResult === undefined; | |
if(mutated && !unchanged){ | |
isError = newResult instanceof Error; | |
} | |
listener.deferred[unchanged && isError ? "reject" : "resolve"](unchanged ? result : newResult); | |
} | |
catch (e) { | |
listener.deferred.reject(e); | |
} | |
}else { | |
if(isError){ | |
listener.deferred.reject(result); | |
}else{ | |
listener.deferred.resolve(result); | |
} | |
} | |
} | |
} | |
// calling resolve will resolve the promise | |
this.resolve = this.callback = function(value){ | |
// summary: | |
// Fulfills the Deferred instance successfully with the provide value | |
this.fired = 0; | |
this.results = [value, null]; | |
complete(value); | |
}; | |
// calling error will indicate that the promise failed | |
this.reject = this.errback = function(error){ | |
// summary: | |
// Fulfills the Deferred instance as an error with the provided error | |
isError = true; | |
this.fired = 1; | |
complete(error); | |
this.results = [null, error]; | |
if(!error || error.log !== false){ | |
(dojo.config.deferredOnError || function(x){ console.error(x); })(error); | |
} | |
}; | |
// call progress to provide updates on the progress on the completion of the promise | |
this.progress = function(update){ | |
// summary | |
// Send progress events to all listeners | |
var listener = nextListener; | |
while(listener){ | |
var progress = listener.progress; | |
progress && progress(update); | |
listener = listener.next; | |
} | |
}; | |
this.addCallbacks = function(/*Function?*/callback, /*Function?*/errback){ | |
this.then(callback, errback, mutator); | |
return this; | |
}; | |
// provide the implementation of the promise | |
this.then = promise.then = function(/*Function?*/resolvedCallback, /*Function?*/errorCallback, /*Function?*/progressCallback){ | |
// summary: | |
// Adds a fulfilledHandler, errorHandler, and progressHandler to be called for | |
// completion of a promise. The fulfilledHandler is called when the promise | |
// is fulfilled. The errorHandler is called when a promise fails. The | |
// progressHandler is called for progress events. All arguments are optional | |
// and non-function values are ignored. The progressHandler is not only an | |
// optional argument, but progress events are purely optional. Promise | |
// providers are not required to ever create progress events. | |
// | |
// This function will return a new promise that is fulfilled when the given | |
// fulfilledHandler or errorHandler callback is finished. This allows promise | |
// operations to be chained together. The value returned from the callback | |
// handler is the fulfillment value for the returned promise. If the callback | |
// throws an error, the returned promise will be moved to failed state. | |
// | |
// example: | |
// An example of using a CommonJS compliant promise: | |
// | asyncComputeTheAnswerToEverything(). | |
// | then(addTwo). | |
// | then(printResult, onError); | |
// | >44 | |
// | |
var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel); | |
var listener = { | |
resolved: resolvedCallback, | |
error: errorCallback, | |
progress: progressCallback, | |
deferred: returnDeferred | |
}; | |
if(nextListener){ | |
head = head.next = listener; | |
} | |
else{ | |
nextListener = head = listener; | |
} | |
if(finished){ | |
notify(); | |
} | |
return returnDeferred.promise; | |
}; | |
var deferred = this; | |
this.cancel = promise.cancel = function () { | |
// summary: | |
// Cancels the asynchronous operation | |
if(!finished){ | |
var error = canceller && canceller(deferred); | |
if(!finished){ | |
if (!(error instanceof Error)) { | |
error = new Error(error); | |
} | |
error.log = false; | |
deferred.reject(error); | |
} | |
} | |
}; | |
freeze(promise); | |
}; | |
dojo.extend(dojo.Deferred, { | |
addCallback: function (/*Function*/callback) { | |
return this.addCallbacks(dojo.hitch.apply(dojo, arguments)); | |
}, | |
addErrback: function (/*Function*/errback) { | |
return this.addCallbacks(null, dojo.hitch.apply(dojo, arguments)); | |
}, | |
addBoth: function (/*Function*/callback) { | |
var enclosed = dojo.hitch.apply(dojo, arguments); | |
return this.addCallbacks(enclosed, enclosed); | |
}, | |
fired: -1 | |
}); | |
})(); | |
dojo.when = function(promiseOrValue, /*Function?*/callback, /*Function?*/errback, /*Function?*/progressHandler){ | |
// summary: | |
// This provides normalization between normal synchronous values and | |
// asynchronous promises, so you can interact with them in a common way | |
// example: | |
// | function printFirstAndList(items){ | |
// | dojo.when(findFirst(items), console.log); | |
// | dojo.when(findLast(items), console.log); | |
// | } | |
// | function findFirst(items){ | |
// | return dojo.when(items, function(items){ | |
// | return items[0]; | |
// | }); | |
// | } | |
// | function findLast(items){ | |
// | return dojo.when(items, function(items){ | |
// | return items[items.length]; | |
// | }); | |
// | } | |
// And now all three of his functions can be used sync or async. | |
// | printFirstAndLast([1,2,3,4]) will work just as well as | |
// | printFirstAndLast(dojo.xhrGet(...)); | |
if(promiseOrValue && typeof promiseOrValue.then === "function"){ | |
return promiseOrValue.then(callback, errback, progressHandler); | |
} | |
return callback(promiseOrValue); | |
}; | |
} | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.6.1/dojo-release-1.6.1/dojo/DeferredList.js | |
// | |
///////////////////////////////////////////////////////////////////////////////////////////////////////////// | |
/* | |
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved. | |
Available via Academic Free License >= 2.1 OR the modified BSD license. | |
see: http://dojotoolkit.org/license for details | |
*/ | |
if(!dojo._hasResource["dojo.DeferredList"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code. | |
dojo._hasResource["dojo.DeferredList"] = true; | |
dojo.provide("dojo.DeferredList"); | |
dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*Boolean?*/ fireOnOneErrback, /*Boolean?*/ consumeErrors, /*Function?*/ canceller){ | |
// summary: | |
// Provides event handling for a group of Deferred objects. | |
// description: | |
// DeferredList takes an array of existing deferreds and returns a new deferred of its own | |
// this new deferred will typically have its callback fired when all of the deferreds in | |
// the given list have fired their own deferreds. The parameters `fireOnOneCallback` and | |
// fireOnOneErrback, will fire before all the deferreds as appropriate | |
// | |
// list: | |
// The list of deferreds to be synchronizied with this DeferredList | |
// fireOnOneCallback: | |
// Will cause the DeferredLists callback to be fired as soon as any | |
// of the deferreds in its list have been fired instead of waiting until | |
// the entire list has finished | |
// fireonOneErrback: | |
// Will cause the errback to fire upon any of the deferreds errback | |
// canceller: | |
// A deferred canceller function, see dojo.Deferred | |
var resultList = []; | |
dojo.Deferred.call(this); | |
var self = this; | |
if(list.length === 0 && !fireOnOneCallback){ | |
this.resolve([0, []]); | |
} | |
var finished = 0; | |
dojo.forEach(list, function(item, i){ | |
item.then(function(result){ | |
if(fireOnOneCallback){ | |
self.resolve([i, result]); | |
}else{ | |
addResult(true, result); | |
} | |
},function(error){ | |
if(fireOnOneErrback){ | |
self.reject(error); | |
}else{ | |
addResult(false, error); | |
} | |
if(consumeErrors){ | |
return null; | |
} | |
throw error; | |
}); | |
function addResult(succeeded, result){ | |
resultList[i] = [succeeded, result]; | |
finished++; | |
if(finished === list.length){ | |
self.resolve(resultList); | |
} | |
} | |
}); | |
}; | |
dojo.DeferredList.prototype = new dojo.Deferred(); | |
dojo.DeferredList.prototype.gatherResults= function(deferredList){ | |
// summary: | |
// Gathers the results of the deferreds for packaging | |
// as the parameters to the Deferred Lists' callback | |
var d = new dojo.DeferredList(deferredList, false, true, false); | |
d.addCallback(function(results){ | |
var ret = []; | |
dojo.forEach(results, function(result){ | |
ret.push(result[1]); | |
}); | |
return ret; | |
}); | |
return d; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.7.4/dojo-release-1.7.4/dojo/_base/Deferred.js | |
// | |
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
define("dojo/_base/Deferred", ["./kernel", "./lang"], function(dojo, lang){ | |
var mutator = function(){}; | |
var freeze = Object.freeze || function(){}; | |
dojo.Deferred = function(/*Function?*/ canceller){ | |
var result, finished, isError, head, nextListener; | |
var promise = (this.promise = {}); | |
function complete(value){ | |
if(finished){ | |
throw new Error("This deferred has already been resolved"); | |
} | |
result = value; | |
finished = true; | |
notify(); | |
} | |
function notify(){ | |
var mutated; | |
while(!mutated && nextListener){ | |
var listener = nextListener; | |
nextListener = nextListener.next; | |
if((mutated = (listener.progress == mutator))){ // assignment and check | |
finished = false; | |
} | |
var func = (isError ? listener.error : listener.resolved); | |
if(func){ | |
try{ | |
var newResult = func(result); | |
if (newResult && typeof newResult.then === "function"){ | |
newResult.then(lang.hitch(listener.deferred, "resolve"), | |
lang.hitch(listener.deferred, "reject"), | |
lang.hitch(listener.deferred, "progress")); | |
continue; | |
} | |
var unchanged = mutated && newResult === undefined; | |
if(mutated && !unchanged){ | |
isError = newResult instanceof Error; | |
} | |
listener.deferred[unchanged && isError ? "reject" : "resolve"] | |
(unchanged ? result : newResult); | |
}catch(e){ | |
listener.deferred.reject(e); | |
} | |
}else{ | |
if(isError){ | |
listener.deferred.reject(result); | |
}else{ | |
listener.deferred.resolve(result); | |
} | |
} | |
} | |
} | |
this.resolve = this.callback = function(value){ | |
this.fired = 0; | |
this.results = [value, null]; | |
complete(value); | |
}; | |
this.reject = this.errback = function(error){ | |
isError = true; | |
this.fired = 1; | |
complete(error); | |
this.results = [null, error]; | |
if(!error || error.log !== false){ | |
(dojo.config.deferredOnError || function(x){ console.error(x); })(error); | |
} | |
}; | |
this.progress = function(update){ | |
var listener = nextListener; | |
while(listener){ | |
var progress = listener.progress; | |
progress && progress(update); | |
listener = listener.next; | |
} | |
}; | |
this.addCallbacks = function(callback, errback){ | |
this.then(callback, errback, mutator); | |
return this; // dojo.Deferred | |
}; | |
promise.then = this.then = function(resolvedCallback, errorCallback, progressCallback){ | |
var returnDeferred = progressCallback == mutator ? this : new dojo.Deferred(promise.cancel); | |
var listener = { | |
resolved: resolvedCallback, | |
error: errorCallback, | |
progress: progressCallback, | |
deferred: returnDeferred | |
}; | |
if(nextListener){ | |
head = head.next = listener; | |
} | |
else{ | |
nextListener = head = listener; | |
} | |
if(finished){ | |
notify(); | |
} | |
return returnDeferred.promise; // Promise | |
}; | |
var deferred = this; | |
promise.cancel = this.cancel = function (){ | |
if(!finished){ | |
var error = canceller && canceller(deferred); | |
if(!finished){ | |
if (!(error instanceof Error)){ | |
error = new Error(error); | |
} | |
error.log = false; | |
deferred.reject(error); | |
} | |
} | |
}; | |
freeze(promise); | |
}; | |
lang.extend(dojo.Deferred, { | |
addCallback: function (/*Function*/ callback){ | |
return this.addCallbacks(lang.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addErrback: function (/*Function*/ errback){ | |
return this.addCallbacks(null, lang.hitch.apply(dojo, arguments)); // dojo.Deferred | |
}, | |
addBoth: function (/*Function*/ callback){ | |
var enclosed = lang.hitch.apply(dojo, arguments); | |
return this.addCallbacks(enclosed, enclosed); // dojo.Deferred | |
}, | |
fired: -1 | |
}); | |
dojo.Deferred.when = dojo.when = function(promiseOrValue, callback, errback, progressHandler){ | |
if(promiseOrValue && typeof promiseOrValue.then === "function"){ | |
return promiseOrValue.then(callback, errback, progressHandler); | |
} | |
return callback ? callback(promiseOrValue) : promiseOrValue; // Promise | |
}; | |
return dojo.Deferred; | |
}); | |
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.7.4/dojo-release-1.7.4/dojo/DeferredList.js | |
// | |
//////////////////////////////////////////////////////////////////////////////////////////////////// | |
define("dojo/DeferredList", ["./_base/kernel", "./_base/Deferred", "./_base/array"], function(dojo, Deferred, darray) { | |
dojo.DeferredList = function( list, fireOnOneCallback, fireOnOneErrback, consumeErrors, canceller){ | |
var resultList = []; | |
Deferred.call(this); | |
var self = this; | |
if(list.length === 0 && !fireOnOneCallback){ | |
this.resolve([0, []]); | |
} | |
var finished = 0; | |
darray.forEach(list, function(item, i){ | |
item.then(function(result){ | |
if(fireOnOneCallback){ | |
self.resolve([i, result]); | |
}else{ | |
addResult(true, result); | |
} | |
},function(error){ | |
if(fireOnOneErrback){ | |
self.reject(error); | |
}else{ | |
addResult(false, error); | |
} | |
if(consumeErrors){ | |
return null; | |
} | |
throw error; | |
}); | |
function addResult(succeeded, result){ | |
resultList[i] = [succeeded, result]; | |
finished++; | |
if(finished === list.length){ | |
self.resolve(resultList); | |
} | |
} | |
}); | |
}; | |
dojo.DeferredList.prototype = new Deferred(); | |
dojo.DeferredList.prototype.gatherResults = function(deferredList){ | |
var d = new dojo.DeferredList(deferredList, false, true, false); | |
d.addCallback(function(results){ | |
var ret = []; | |
darray.forEach(results, function(result){ | |
ret.push(result[1]); | |
}); | |
return ret; | |
}); | |
return d; | |
}; | |
return dojo.DeferredList; | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.8.3/dojo-release-1.8.3/dojo/Deferred.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////// | |
var has = require('./has') | |
, lang = require('./_base/lang') | |
, CancelError = require('./errors/CancelError"') | |
, Promise = require('./promise/Promise'); | |
var PROGRESS = 0, | |
RESOLVED = 1, | |
REJECTED = 2; | |
var signalWaiting = function(waiting, type, result, rejection, deferred){ | |
for(var i = 0; i < waiting.length; i++){ | |
signalListener(waiting[i], type, result, rejection); | |
} | |
}; | |
var signalListener = function(listener, type, result, rejection){ | |
var func = listener[type]; | |
var deferred = listener.deferred; | |
if (func){ | |
try{ | |
var newResult = func(result); | |
if (type === PROGRESS){ | |
if (typeof newResult !== "undefined"){ | |
signalDeferred(deferred, type, newResult); | |
} | |
} | |
else{ | |
if(newResult && typeof newResult.then === "function"){ | |
listener.cancel = newResult.cancel; | |
newResult.then(makeDeferredSignaler(deferred, RESOLVED), | |
makeDeferredSignaler(deferred, REJECTED), | |
makeDeferredSignaler(deferred, PROGRESS)); | |
return; | |
} | |
signalDeferred(deferred, RESOLVED, newResult); | |
} | |
} | |
catch(error){ | |
signalDeferred(deferred, REJECTED, error); | |
} | |
} | |
else{ | |
signalDeferred(deferred, type, result); | |
} | |
}; | |
var makeDeferredSignaler = function(deferred, type){ | |
return function(value){ | |
signalDeferred(deferred, type, value); | |
}; | |
}; | |
var signalDeferred = function(deferred, type, result){ | |
if(!deferred.isCanceled()){ | |
switch(type){ | |
case PROGRESS: | |
deferred.progress(result); | |
break; | |
case RESOLVED: | |
deferred.resolve(result); | |
break; | |
case REJECTED: | |
deferred.reject(result); | |
break; | |
} | |
} | |
}; | |
var Deferred = function(canceler){ | |
var deferred = this; | |
var promise = this.promise = new Promise(); | |
var fulfilled, result, rejection; | |
var canceled = false; | |
var waiting = []; | |
this.isResolved = promise.isResolved = function(){ | |
return fulfilled === RESOLVED; | |
}; | |
this.isRejected = promise.isRejected = function(){ | |
return fulfilled === REJECTED; | |
}; | |
this.isFulfilled = promise.isFulfilled = function(){ | |
return !!fulfilled; | |
}; | |
this.isCanceled = promise.isCanceled = function(){ | |
return canceled; | |
}; | |
this.progress = function(update, strict){ | |
if (!fulfilled){ | |
signalWaiting(waiting, PROGRESS, update, null, deferred); | |
return promise; | |
} | |
else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
} | |
else{ | |
return promise; | |
} | |
}; | |
this.resolve = function(value, strict){ | |
if(!fulfilled){ | |
signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred); | |
waiting = null; | |
return promise; | |
} | |
else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
} | |
else{ | |
return promise; | |
} | |
}; | |
var reject = this.reject = function(error, strict){ | |
if (!fulfilled){ | |
signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred); | |
waiting = null; | |
return promise; | |
} | |
else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
} | |
else{ | |
return promise; | |
} | |
}; | |
this.then = promise.then = function(callback, errback, progback){ | |
var listener = [progback, callback, errback]; | |
// Ensure we cancel the promise we're waiting for, or if callback/errback | |
// have returned a promise, cancel that one. | |
listener.cancel = promise.cancel; | |
listener.deferred = new Deferred(function(reason){ | |
// Check whether cancel is really available, returned promises are not | |
// required to expose `cancel` | |
return listener.cancel && listener.cancel(reason); | |
}); | |
if(fulfilled && !waiting){ | |
signalListener(listener, fulfilled, result, rejection); | |
} | |
else{ | |
waiting.push(listener); | |
} | |
return listener.deferred.promise; | |
}; | |
this.cancel = promise.cancel = function(reason, strict){ | |
if (!fulfilled){ | |
if (canceler){ | |
var returnedReason = canceler(reason); | |
reason = typeof returnedReason === "undefined" ? reason : returnedReason; | |
} | |
canceled = true; | |
if (!fulfilled){ | |
if (typeof reason === "undefined"){ | |
reason = new CancelError(); | |
} | |
reject(reason); | |
return reason; | |
} | |
else if(fulfilled === REJECTED && result === reason){ | |
return reason; | |
} | |
} | |
else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
} | |
}; | |
freezeObject(promise); | |
}; | |
Deferred.prototype.toString = function(){ | |
return "[object Deferred]"; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.8.3/dojo-release-1.8.3/dojo/Deferred.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////// | |
define("dojo/Deferred", [ | |
"./has", | |
"./_base/lang", | |
"./errors/CancelError", | |
"./promise/Promise", | |
"./promise/instrumentation" | |
], function(has, lang, CancelError, Promise, instrumentation){ | |
"use strict"; | |
// module: | |
// dojo/Deferred | |
var PROGRESS = 0, | |
RESOLVED = 1, | |
REJECTED = 2; | |
var FULFILLED_ERROR_MESSAGE = "This deferred has already been fulfilled."; | |
var freezeObject = Object.freeze || function(){}; | |
var signalWaiting = function(waiting, type, result, rejection, deferred){ | |
if( 1 ){ | |
if(type === REJECTED && Deferred.instrumentRejected && waiting.length === 0){ | |
Deferred.instrumentRejected(result, false, rejection, deferred); | |
} | |
} | |
for(var i = 0; i < waiting.length; i++){ | |
signalListener(waiting[i], type, result, rejection); | |
} | |
}; | |
var signalListener = function(listener, type, result, rejection){ | |
var func = listener[type]; | |
var deferred = listener.deferred; | |
if(func){ | |
try{ | |
var newResult = func(result); | |
if(type === PROGRESS){ | |
if(typeof newResult !== "undefined"){ | |
signalDeferred(deferred, type, newResult); | |
} | |
}else{ | |
if(newResult && typeof newResult.then === "function"){ | |
listener.cancel = newResult.cancel; | |
newResult.then( | |
// Only make resolvers if they're actually going to be used | |
makeDeferredSignaler(deferred, RESOLVED), | |
makeDeferredSignaler(deferred, REJECTED), | |
makeDeferredSignaler(deferred, PROGRESS)); | |
return; | |
} | |
signalDeferred(deferred, RESOLVED, newResult); | |
} | |
}catch(error){ | |
signalDeferred(deferred, REJECTED, error); | |
} | |
}else{ | |
signalDeferred(deferred, type, result); | |
} | |
if( 1 ){ | |
if(type === REJECTED && Deferred.instrumentRejected){ | |
Deferred.instrumentRejected(result, !!func, rejection, deferred.promise); | |
} | |
} | |
}; | |
var makeDeferredSignaler = function(deferred, type){ | |
return function(value){ | |
signalDeferred(deferred, type, value); | |
}; | |
}; | |
var signalDeferred = function(deferred, type, result){ | |
if(!deferred.isCanceled()){ | |
switch(type){ | |
case PROGRESS: | |
deferred.progress(result); | |
break; | |
case RESOLVED: | |
deferred.resolve(result); | |
break; | |
case REJECTED: | |
deferred.reject(result); | |
break; | |
} | |
} | |
}; | |
var Deferred = function(canceler){ | |
// summary: | |
// Creates a new deferred. This API is preferred over | |
// `dojo/_base/Deferred`. | |
// description: | |
// Creates a new deferred, as an abstraction over (primarily) | |
// asynchronous operations. The deferred is the private interface | |
// that should not be returned to calling code. That's what the | |
// `promise` is for. See `dojo/promise/Promise`. | |
// canceler: Function? | |
// Will be invoked if the deferred is canceled. The canceler | |
// receives the reason the deferred was canceled as its argument. | |
// The deferred is rejected with its return value, or a new | |
// `dojo/errors/CancelError` instance. | |
// promise: dojo/promise/Promise | |
// The public promise object that clients can add callbacks to. | |
var promise = this.promise = new Promise(); | |
var deferred = this; | |
var fulfilled, result, rejection; | |
var canceled = false; | |
var waiting = []; | |
if( 1 && Error.captureStackTrace){ | |
Error.captureStackTrace(deferred, Deferred); | |
Error.captureStackTrace(promise, Deferred); | |
} | |
this.isResolved = promise.isResolved = function(){ | |
// summary: | |
// Checks whether the deferred has been resolved. | |
// returns: Boolean | |
return fulfilled === RESOLVED; | |
}; | |
this.isRejected = promise.isRejected = function(){ | |
// summary: | |
// Checks whether the deferred has been rejected. | |
// returns: Boolean | |
return fulfilled === REJECTED; | |
}; | |
this.isFulfilled = promise.isFulfilled = function(){ | |
// summary: | |
// Checks whether the deferred has been resolved or rejected. | |
// returns: Boolean | |
return !!fulfilled; | |
}; | |
this.isCanceled = promise.isCanceled = function(){ | |
// summary: | |
// Checks whether the deferred has been canceled. | |
// returns: Boolean | |
return canceled; | |
}; | |
this.progress = function(update, strict){ | |
// summary: | |
// Emit a progress update on the deferred. | |
// description: | |
// Emit a progress update on the deferred. Progress updates | |
// can be used to communicate updates about the asynchronous | |
// operation before it has finished. | |
// update: any | |
// The progress update. Passed to progbacks. | |
// strict: Boolean? | |
// If strict, will throw an error if the deferred has already | |
// been fulfilled and consequently no progress can be emitted. | |
// returns: dojo/promise/Promise | |
// Returns the original promise for the deferred. | |
if(!fulfilled){ | |
signalWaiting(waiting, PROGRESS, update, null, deferred); | |
return promise; | |
}else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
}else{ | |
return promise; | |
} | |
}; | |
this.resolve = function(value, strict){ | |
// summary: | |
// Resolve the deferred. | |
// description: | |
// Resolve the deferred, putting it in a success state. | |
// value: any | |
// The result of the deferred. Passed to callbacks. | |
// strict: Boolean? | |
// If strict, will throw an error if the deferred has already | |
// been fulfilled and consequently cannot be resolved. | |
// returns: dojo/promise/Promise | |
// Returns the original promise for the deferred. | |
if(!fulfilled){ | |
// Set fulfilled, store value. After signaling waiting listeners unset | |
// waiting. | |
signalWaiting(waiting, fulfilled = RESOLVED, result = value, null, deferred); | |
waiting = null; | |
return promise; | |
}else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
}else{ | |
return promise; | |
} | |
}; | |
var reject = this.reject = function(error, strict){ | |
// summary: | |
// Reject the deferred. | |
// description: | |
// Reject the deferred, putting it in an error state. | |
// error: any | |
// The error result of the deferred. Passed to errbacks. | |
// strict: Boolean? | |
// If strict, will throw an error if the deferred has already | |
// been fulfilled and consequently cannot be rejected. | |
// returns: dojo/promise/Promise | |
// Returns the original promise for the deferred. | |
if(!fulfilled){ | |
if( 1 && Error.captureStackTrace){ | |
Error.captureStackTrace(rejection = {}, reject); | |
} | |
signalWaiting(waiting, fulfilled = REJECTED, result = error, rejection, deferred); | |
waiting = null; | |
return promise; | |
}else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
}else{ | |
return promise; | |
} | |
}; | |
this.then = promise.then = function(callback, errback, progback){ | |
// summary: | |
// Add new callbacks to the deferred. | |
// description: | |
// Add new callbacks to the deferred. Callbacks can be added | |
// before or after the deferred is fulfilled. | |
// callback: Function? | |
// Callback to be invoked when the promise is resolved. | |
// Receives the resolution value. | |
// errback: Function? | |
// Callback to be invoked when the promise is rejected. | |
// Receives the rejection error. | |
// progback: Function? | |
// Callback to be invoked when the promise emits a progress | |
// update. Receives the progress update. | |
// returns: dojo/promise/Promise | |
// Returns a new promise for the result of the callback(s). | |
// This can be used for chaining many asynchronous operations. | |
var listener = [progback, callback, errback]; | |
// Ensure we cancel the promise we're waiting for, or if callback/errback | |
// have returned a promise, cancel that one. | |
listener.cancel = promise.cancel; | |
listener.deferred = new Deferred(function(reason){ | |
// Check whether cancel is really available, returned promises are not | |
// required to expose `cancel` | |
return listener.cancel && listener.cancel(reason); | |
}); | |
if(fulfilled && !waiting){ | |
signalListener(listener, fulfilled, result, rejection); | |
}else{ | |
waiting.push(listener); | |
} | |
return listener.deferred.promise; | |
}; | |
this.cancel = promise.cancel = function(reason, strict){ | |
// summary: | |
// Inform the deferred it may cancel its asynchronous operation. | |
// description: | |
// Inform the deferred it may cancel its asynchronous operation. | |
// The deferred's (optional) canceler is invoked and the | |
// deferred will be left in a rejected state. Can affect other | |
// promises that originate with the same deferred. | |
// reason: any | |
// A message that may be sent to the deferred's canceler, | |
// explaining why it's being canceled. | |
// strict: Boolean? | |
// If strict, will throw an error if the deferred has already | |
// been fulfilled and consequently cannot be canceled. | |
// returns: any | |
// Returns the rejection reason if the deferred was canceled | |
// normally. | |
if(!fulfilled){ | |
// Cancel can be called even after the deferred is fulfilled | |
if(canceler){ | |
var returnedReason = canceler(reason); | |
reason = typeof returnedReason === "undefined" ? reason : returnedReason; | |
} | |
canceled = true; | |
if(!fulfilled){ | |
// Allow canceler to provide its own reason, but fall back to a CancelError | |
if(typeof reason === "undefined"){ | |
reason = new CancelError(); | |
} | |
reject(reason); | |
return reason; | |
}else if(fulfilled === REJECTED && result === reason){ | |
return reason; | |
} | |
}else if(strict === true){ | |
throw new Error(FULFILLED_ERROR_MESSAGE); | |
} | |
}; | |
freezeObject(promise); | |
}; | |
Deferred.prototype.toString = function(){ | |
// returns: String | |
// Returns `[object Deferred]`. | |
return "[object Deferred]"; | |
}; | |
if(instrumentation){ | |
instrumentation(Deferred); | |
} | |
return Deferred; | |
}); | |
////////////////////////////////////////////////////////////////////////////////////////////// | |
// | |
// http://download.dojotoolkit.org/release-1.8.3/dojo-release-1.8.3/dojo/DeferredList.js | |
// | |
////////////////////////////////////////////////////////////////////////////////////////////// | |
define("dojo/DeferredList", ["./_base/kernel", "./_base/Deferred", "./_base/array"], function(dojo, Deferred, darray){ | |
// module: | |
// dojo/DeferredList | |
dojo.DeferredList = function(/*Array*/ list, /*Boolean?*/ fireOnOneCallback, /*Boolean?*/ fireOnOneErrback, /*Boolean?*/ consumeErrors, /*Function?*/ canceller){ | |
// summary: | |
// Deprecated, use dojo/promise/all instead. | |
// Provides event handling for a group of Deferred objects. | |
// description: | |
// DeferredList takes an array of existing deferreds and returns a new deferred of its own | |
// this new deferred will typically have its callback fired when all of the deferreds in | |
// the given list have fired their own deferreds. The parameters `fireOnOneCallback` and | |
// fireOnOneErrback, will fire before all the deferreds as appropriate | |
// list: | |
// The list of deferreds to be synchronizied with this DeferredList | |
// fireOnOneCallback: | |
// Will cause the DeferredLists callback to be fired as soon as any | |
// of the deferreds in its list have been fired instead of waiting until | |
// the entire list has finished | |
// fireonOneErrback: | |
// Will cause the errback to fire upon any of the deferreds errback | |
// canceller: | |
// A deferred canceller function, see dojo.Deferred | |
var resultList = []; | |
Deferred.call(this); | |
var self = this; | |
if(list.length === 0 && !fireOnOneCallback){ | |
this.resolve([0, []]); | |
} | |
var finished = 0; | |
darray.forEach(list, function(item, i){ | |
item.then(function(result){ | |
if(fireOnOneCallback){ | |
self.resolve([i, result]); | |
}else{ | |
addResult(true, result); | |
} | |
},function(error){ | |
if(fireOnOneErrback){ | |
self.reject(error); | |
}else{ | |
addResult(false, error); | |
} | |
if(consumeErrors){ | |
return null; | |
} | |
throw error; | |
}); | |
function addResult(succeeded, result){ | |
resultList[i] = [succeeded, result]; | |
finished++; | |
if(finished === list.length){ | |
self.resolve(resultList); | |
} | |
} | |
}); | |
}; | |
dojo.DeferredList.prototype = new Deferred(); | |
dojo.DeferredList.prototype.gatherResults = function(deferredList){ | |
// summary: | |
// Gathers the results of the deferreds for packaging | |
// as the parameters to the Deferred Lists' callback | |
// deferredList: dojo/DeferredList | |
// The deferred list from which this function gathers results. | |
// returns: dojo/DeferredList | |
// The newly created deferred list which packs results as | |
// parameters to its callback. | |
var d = new dojo.DeferredList(deferredList, false, true, false); | |
d.addCallback(function(results){ | |
var ret = []; | |
darray.forEach(results, function(result){ | |
ret.push(result[1]); | |
}); | |
return ret; | |
}); | |
return d; | |
}; | |
return dojo.DeferredList; | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment