Skip to content

Instantly share code, notes, and snippets.

@joseanpg
Last active December 10, 2015 10:29
Show Gist options
  • Save joseanpg/4421431 to your computer and use it in GitHub Desktop.
Save joseanpg/4421431 to your computer and use it in GitHub Desktop.
Dojo Deferred.js & DeferredList.js
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
});
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
});
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
});
//////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
}
});
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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
//////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
};
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
};
}
////////////////////////////////////////////////////////////////////////////////////////////////////
//
// 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;
});
//////////////////////////////////////////////////////////////////////////////////////////////
//
// 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]";
};
//////////////////////////////////////////////////////////////////////////////////////////////
//
// 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