1

How can I do a spinlock in javascript?

I'm trying to load a bunch of images and I can only move forward after everything is loaded, so I have a spinlock like

for(...)
   image[i].onload = function() { ++imagesloaded; }

while(imagesloaded != totalimages)
{
}

And it crashes my browser. Is there a better way to do it? Or a yield / sleep function I'm missing?

user1032861
  • 487
  • 3
  • 11
  • 19

3 Answers3

3

Short answer: don't spinlock.


Longer answer: here's how to do it:

var imagesLoaded = 0;
var totalImages = 42;

function handleImageLoad()
{
    imagesLoaded++;
    if (imagesLoaded === totalImages)
    {
        doSomething();
    }
}

for (var i=0; i<totalImages; i++)
{
    image[i].onload = handleImageLoad;
}

In general, when you want to sleep/wait/spin in JavaScript, instead think about solving the problem in terms of callbacks (and setTimeout/setInterval).

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
  • 1
    Keep in mind that you have to set the `onload()` handler BEFORE the `.src` is set on the image. Otherwise you may miss the `onload()` event in some browsers if the image gets loaded from the cache (and thus loaded very quickly). – jfriend00 Nov 06 '11 at 22:57
0

The answers above aren't useful as spinlocks may be required because of limitations/bugs in browsers. For instance safari (hopefully not future versions) requires the use of method window.open when you want to generate a file in javascript. The consequence of this is that you cannot generate the file using any callbacks (because of popup blockers), this in effect forces the use of a dialog window that first calls the file generation function (using callbacks) and then a button that downloads the file. Because spinlocks don't work the code becomes the following:

function process(callback) {
  processCallbackData = null; // global var that must be a unique name
  callback(function(data) {
     processCallbackData = data;
  });
}

function fowardButton() {
  if(processCallbackData!=null) {
     goForwardUsingCallbackIncompatibleCode();
  } else {
     displayStillLoadingWarning();
  }
}
user6830669
  • 161
  • 4
-1

Don't use a loop to check. Check in the event handler function. (So you only do the check when an image has loaded, not continuously and as quickly as possible)

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • [Oh, you mean like this? `:P`](http://stackoverflow.com/questions/8030971/spinlock-in-javascript/8030988#8030988) – Matt Ball Nov 06 '11 at 22:43