(update: it seems using implementation of #5 in [548] (DeferredList?) could accomplish the same thing? how?)
I had a problem that in many cases, I need to retrieve several files and get a callback triggered when ALL of them have been retrieved. I could not find this feature in MochiKit yet, so this convenience function does that. Perhaps this is a common enough need that something like this could be added in MochiKit itself?
Hopefully this helps anyone else who may have a similar need. The code works for me, but I am sure it can be improved and thus hope that it will get the benefit of someone more knowledgeable than myself taking a look.
Some clarification of the parameter names used in code below: rid='request id', md="multi-Deferred".
// CONSTANTS (should be in mochikit itself / are somewhere already?)
var deferred_unfinished = -1;
var deferred_ready = 0;
var deferred_error = 1;
/* tasks are {rid: url} 'assoc. arrays' */
function doNamedXMLHttpRequests(requests){
// subrequests
var deferreds = new Array();
// map deferred ids to request ids
var deferred2rid = new Array();
// result deferred ("multideferred")
var md = new Deferred();
// callback parameter
var results = new Array();
for (rid in requests) {
results[rid] = null;
}
/* The callback checks every deferred
and returns if any of them is not ready*/
function multiCallBack(r){
var allreceived = true;
for (var idx in deferreds){
var deferred = deferreds[idx];
var status = deferred.fired;
var rid = deferred2rid[deferred.id];
var url = requests[rid];
switch (status) {
case deferred_unfinished:
//logDebug("doNamedXMLHttpRequests:", rid, "(" + url + ")", "is in UNFINISHED state");
allreceived = false;
break;
case deferred_ready:
if (! results[rid]) {
results[rid] = r;
//logDebug("doNamedXMLHttpRequests:", rid, "(" + url + ")", "finished OK");
}
break;
case deferred_error:
logError("doNamedXMLHttpRequests:", rid, "(" + url + ")", "FAILED");
allreceived = false;
md.errback(deferred);
return;
} // end switch
} // end for
if (allreceived) {
//logDebug("doNamedXMLHttpRequests: task", "(" + keys(results).length + " requests)", "finished ok");
md.callback(results);
}
}
//logDebug("doNamedXMLHttpRequests: starting a", keys(requests).length + "-part task");
for (var rid in requests){
var url = requests[rid];
var d = doSimpleXMLHttpRequest(url);
deferred2rid[d.id] = rid;
deferreds.push(d);
d.addBoth(multiCallBack);
}
return md;
}
