gromiczek
gromiczek

Reputation: 3020

How to load images with chained Promises

I'm having trouble loading images with a script of chained promises - they turn up undefined by the end. I also have a 404 error I don't quite understand as I've confirmed that all the sources are valid, but admit I'm still a noob to debugging in an async context. Here is the fiddle in question. I've been chewing on this one for a couple days now and could use a nudge or two to get me headed in the right direction. I think this may be the problem area:

function loadImagePromises() {
    var imageLoadPromises = [];
    for ( var i  = 0; i < sources.length; i++ ) {
        imageLoadPromises.push( 
            imgLoad( sources[i] ).then(function(response) {
                var myImage = new Image();
                myImage.src = response; // response is a blob
            }, function(Error) {
                console.log("There was an error when the image was loaded after download: " + Error);
            }) );
    }
    console.log( imageLoadPromises );
    return imageLoadPromises;
}

As context, I'm writing an image loader script using promises for a Three.js program I have. No need to load the images to the DOM - I'll use them later as textures in a WebGL visualization.

NOTE: Here's an earlier and simpler fiddle working end-to-end and outputting to the DOM.

Upvotes: 0

Views: 1081

Answers (1)

mczepiel
mczepiel

Reputation: 711

Probably some other considerations here but your success handler isn't returning anything explicitly, so it's implicitly returning undefined:

function(response) {
  var myImage = new Image();
  myImage.src = response;
  // if you want the promise to resolve to a useful value put
  // it below, with whatever you want e.g:
  return myImage;
}

RE: Errors: You should probably not shadow Error in your error handler, just use lowercase error. Also, when using console.log/console.error you can use , to chain parts of the message which usually presents a richer message than the string used when concatenating.

e.g.

console.error("There was an error when the image was loaded after download: ", error);

FWIW you could also reduce some of the tedious iteration/collection here by using map to map each source to a promise:

function loadImagePromises() {
  return sources.map(function(source) {
    return imgLoad(source).then(function(response) {
    // ...
    });
}

EDIT Re: waiting for image objects to have actually loaded

return imgLoad(source).then(function(response) {
  var imageURL = window.URL.createObjectURL(response);
  var myImage = new Image();

  return new Promise(function(resolve, reject) {
    myImage.onload = function () {
      // image has loaded
      resolve(myImage);
    }

    // TODO error handling

    myImage.src = imageURL;
  });
}, console.error);
});

Upvotes: 2

Related Questions