50Special
50Special

Reputation: 33

Trouble with JS function execution

I've got a little problem with JS Function Execution. That's the code:

function CaricaImmagini() {
    //First for loop
    for (i = 0; i < tiles.length; i++)
    {
        tileGraphics[i] = new Image();
        tileGraphics[i].src = tiles[i];

        tileGraphics[i].onload = function() 
        {
            img_loaded++;
            pda.SetPerc(Math.round((70/(tiles.length + img_nec.length))*img_loaded));
            pda.CounterFill();
        }   
    }
    //Second for loop
    for (i=0; i < img_nec.length; i++)
    {
        imgs[i] = new Image();
        imgs[i].src = img_nec[i];

        imgs[i].onload = function() 
        {
            img_loaded++;
            pda.SetPerc(Math.round((70/(tiles.length + img_nec.length))*img_loaded));
            pda.CounterFill();
        }
    }
    //Change % in Canvas
    pda.SetPerc(75);
    pda.CounterFill();
}

The problem is that the functions under 'Change % in Canvas' comment are executed before the for loops. So in the canvas i see first 75% (the setperc function renders % loading), and after that i see the output of these Calc [Math.round((70/(tiles.length + img_nec.length))*img_loaded)]. How can i solve?

Regards, 50Special

Upvotes: 2

Views: 60

Answers (2)

trincot
trincot

Reputation: 351278

This happens because the onload events are triggered later, and only then the callbacks you have defined will be executed. It is thus normal that the lines at the end of your function get executed first -- it could not be any different.

So just put 0% there:

    //Change % in Canvas
    pda.SetPerc(0);
    pda.CounterFill();

If however you want to execute code once all has been loaded, then define a callback. You could do it like this:

function CaricaImmagini(callback) { // notice the parameter that must be passed
    // ...
    tileGraphics[i].onload = function() 
    {
        // ...
        if (img_loaded == tiles.length + img_nec.length && callback) callback(); 
    }
    // ...
    imgs[i].onload = function() 
    {
        // ...
        if (img_loaded == tiles.length + img_nec.length && callback) callback(); 
    }
}

You would then call that function by passing it the callback function:

CaricaImmagini(function () {
    // all is loaded now
    //Change % in Canvas
    pda.SetPerc(75);
    pda.CounterFill();
});

Upvotes: 1

Anton Harald
Anton Harald

Reputation: 5954

Here's a pattern, that might help you:

var nr = 100;
var imgs = [];
var some_sources = ... // list of 100 sources
var imgs_loaded = 0;

for(var i = 0; i < nr; i++) {
   imgs[i] = new Image();
   imgs[i].src = some_sources[i];
   imgs[i].onload = function() {
      imgs_loaded++;
      if (imgs_loaded === nr) {  // when all pictures are loaded
         doSomethingElse();
      }
   }
}

So this let's all the pictures load asynchronously, checking each time an image arrives, if all the images are already loaded. If this is finally true after the last picture is loaded, another function is called.

Upvotes: 1

Related Questions