Promise.jsm demo of Promise.all and Promise.defer
Here's my implementation:

// So we define a function that loads images, and returns a promise for us to listen to
function loadImages(images){

  // We can take advantage of `map` which iterates through an array and makes an array
  // out of the returns of each iteration. In this case, we return a promise for each
  // url, for `Promise.all` to listen to later.
  var promises = images.map(function(url){

    // Create a Deferred object and image, and handle the resolution stuff.
    var deferred = Promise.defer();
    var image = new Image();
    image.onload = function(){deferred.resolve('image success: '+ url);};
    image.onerror = function(){deferred.reject('image failed: ' + url);};
    image.onerror = function(){deferred.reject('image aborted: ' + url);};
    image.src = url;

    // Return the promise, which will be stored in the array, thanks to `map`
    return deferred;
  });

  // Listen on the array of promises (aha moment: jQuery.when == Promises.all, more or less.)
  return Promise.all(promises);
}

// Now we use `loadImages`, loading an array of urls, and listening for notices
loadImages([
  'http://www.mozilla.org/media/img/firefox/favicon.png',
  'https://developer.cdn.mozilla.net/media/redesign/img/favicon32.png'
]).then(function(value){
  console.log('loadImages successful: ' + value);
},function(error){
  console.log('loadImages failed: ' + error);
});


Additional notes:


Don't do [].forEach.call. Aside from looking very hackish, it creates an unnecessary array. Do Array.prototype.forEach.call instead.
I'd avoid using try-catch. While it's a good measure for errors, it's bad for optimization. Some optimizing compilers (I think V8) can't optimize code inside try-catch.
Name your variables and functions properly and verbosely.