nasoj1100
nasoj1100

Reputation: 538

dealing with async code on frontend

I'm pretty new to programming with JS and started with Node. I have been using the async module while working on the backend with the database to deal with async code. What should I be using to deal with async code on the front end. I have the following that checks an array of images to see if they load.

$(document).ready(function () {
    var images = <%- JSON.stringify(images) %>;

    var imagesNotLoading = [];
    images.forEach(function (image) {
        if(!imageLoads(image)) {
           imagesNotLoading.push(image)
    });
    console.log(imagesNotLoading);

    //returns true if image loads successfully
    function imageLoads(src) {
        var img = new Image();
        img.onload = function() {
            return true;
        };
        img.onerror = function() {
            return false;
        };
        img.src = src;
    }
});

The imageLoads function will return undefined or !undefined which is true. What should I be using to wait till the function has returned true or false before pushing it on to the imagesNotLoadingArray. Any help appreciated.

Upvotes: 0

Views: 1213

Answers (2)

burnedikt
burnedikt

Reputation: 1007

If you're using the async-library with node, there is no reason why you shouldn't use the same in your browser to deal with asynchronous code. As soon as you load the browser version of the async library, you can use its async.parallel(...) function to check which of your images are loading and which aren't.

Apart from that, you might wanna take a look at promises, since they greatly simplify dealing with asynchronous code in Javascript - no matter whether in the front- or backend.

Using promises, your code would look something like

$(document).ready(function () {
   var images = <%- JSON.stringify(images) %>;

   var imagesNotLoading = [];
   images.forEach(function (image) {
      imageLoads(image).then(function(){}, function() {
         imagesNotLoading.push(image);
      });
   });

   // returns true if image loads successfully
   function imageLoads(src) {
      var img = new Image();
      return new Promise(function(resolve, reject) {
         img.onload = resolve;
         img.onerror = reject;
         img.src = src;
      });
   }
});

This will wait for all your images to either be loaded or errored and execute the callback afterwards. Since the onload and onerror functions are executed at some time in the future and you don't know yet when this is going to be, you're best of with promises to handle the result of image loading.

Upvotes: 1

Marcos P&#233;rez Gude
Marcos P&#233;rez Gude

Reputation: 22158

You should write the imagesNotLoading array on the error handler.

var images = <%- JSON.stringify(images) %>;

var imagesNotLoading = [];
images.forEach(function (image) {
    imageLoads(image)
});

//returns true if image loads successfully
function imageLoads(src) {
    var img = new Image(src);
    img.onload = function() {
        successFunction(img);
    };
    img.onerror = function() {
        errorFunction(img);
    };
    img.src = src;
}

function errorFunction(img){
    imagesNotLoading.push(img.src);
}
function successFunction(img){
    console.log("Image "+img.src+" was loaded successful!");
}

Upvotes: 2

Related Questions