(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;
}