Control the order of returning callbacks

Hi all

I’m trying to load multiple large images (3600x1800) into a p5 sketch. I can’t use preload because there are over 300 of them and memory issues are crashing the browser. Speed isn’t important though so I’m using callbacks to load and handle them one at once instead like this:

for(var picno=1;picno<=numimages;picno++){
filename="./f"+picno+".png";

loadImage(filename, tempimage => {
    image(tempimage,0,0);
    tempimage.loadPixels();    
    processPixelArray(tempimage.pixels);
});

}

function processPixelArray(){
etc
}

The above works except that I need to process the pixel arrays in the order I loaded the images and as the images have different file sizes, the callbacks are coming out of the order that loadImage was called.

I’ve tried variations along the lines of:

var lock=0;
var picno=1;
while(picno<=numimages){
filename="./f"+picno+".png";
if(lock==0){
lock=1;
loadImage(filename, tempimage => {
image(tempimage,0,0);
tempimage.loadPixels();
processPixelArray(tempimage.pixels);
lock=0;
pickno++;
});
}
}

but that locks up the browser as well.

How can I maintain / keep track of the order of these loadImage calls? Is there a way that I can pass in the current value of picno to the callback function (Then read it back in processPixelArray) so that I can track and reorder the data from the callbacks myself?

Thanks as usual for any help…

Simon

A callback’s parameters are pre-determined. We can’t change the arguments passed to it; b/c obviously it’s not us who invokes it.

However, an inner callback created on-the-fly like you have there can access closures, which are variables & parameters declared in its outer function:

In your case, variable picno is the for ( ; ; ) block’s iterator.

The loadImage()'s callback can use picno as a closure within its body. However there’s a glitch if you do so!

By the time the inner callback is actually invoked, picno will currently have its final value, which is the value of numimages plus 1!

But if you declare picno w/ keyword let instead of var, picno’s current value will be bound for each iteration:

That means that each callback created inside that loop will have its own picno’s value when internally used as a closure.

1 Like

Many thanks for this, GoToLoop. You solved my problem!

  • Simon