Promise.jsm demo of Promise.all and Promise.defer I created this demo example for MDN documentation to show how to use Promise.all and Promise.defer in user created promise. I used lets because I thought if I didn't it would mess it up.

People are recommending I avoid let because the standard is not there yet and it looks like when it lands it will be a little different.  Can you please advise?

The code downloads images from an array and after all images are downloaded it completes the main promise.

Components.utils.import("resource://gre/modules/Promise.jsm");

var myPromise = myUserDefinedPromise();
myPromise.then(
  function(aSuccessReason) {
    alert('myPromise was SUCCESFUL and reason was = "' + aSuccessReason + '"');
  },
  function(aRejectReason) {
    alert('myPromise FAILED for reason = "' + uneval(aRejectReason) + '"');
  }
);

function myUserDefinedPromise() {
  try {
    var mySubPromises = [];

    var imagePaths = ['http://www.mozilla.org/media/img/firefox/favicon.png', 'https://developer.cdn.mozilla.net/media/redesign/img/favicon32.png'];
    [].forEach.call(imagePaths, function(path) {
      let myImage = new Image();
      let loadThisImagePromise = Promise.defer();
      mySubPromises.push(loadThisImagePromise.promise);
      myImage.onload = function() {
        loadThisImagePromise.resolve('Succesfully loaded image at path = "' + path + '" the width of this image is = "' + this.naturalWidth + '".');
        if (!this.naturalWidth) {
          loadThisImagePromise.reject('Image loaded but it has 0 width at path = "' + path + '" the naturalWidth was 0');
        }
      }
      myImage.onerror = function(e) {
        loadThisImagePromise.reject('An error occured while loading path = "' + path + '". The error = ' + uneval(e));
      }
      myImage.onabort = function(e) {
        loadThisImagePromise.reject('Image load was aborted loading path = "' + path + '".');
      }
      myImage.src = path;
    });

    return Promise.all(mySubPromises);
  } catch(ex) {
    return Promise.reject(ex);
  }
}
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.