0

I have an expensive function, createNewWindow(). I want to show a progress indicator when the method gets called, and then hide that indicator when the function finishes. Everything I've tried though, I don't see the progress indicator until the method has finshed, so I'm trying to call that method asychronously (and failing).

I tried this:

$( "#submit" ).click( function () {
    $("#progress").show();
    $.Deferred(createNewWindow());
} );

And the last line of createNewWindow was $("#progress").show(). Didn't work. Before that I tried:

$( "#submit" ).click( function () {
    $("#progress").show();
    setTimeout(createNewWindow(), 0);
} );

Same effect.

What's the right way to do this?

I saw a few other SO posts like this that describe using setInterval or setTimeout, but I was unable to get them to work like I was expecting.

Community
  • 1
  • 1
Nicros
  • 5,031
  • 12
  • 57
  • 101
  • Calling a synchronous function in an asynchronous way does'nt make it so. It will still block the browser, and your best bet is an image of something spinning. – adeneo Apr 05 '13 at 23:16

1 Answers1

3

This is a common mistake. The problem is right here:

setTimeout(createNewWindow(), 0);

This will call createNewWindow immediately and pass the result (probably void) to setTimeout. That's not what you want, you want to pass the function createNewWindow to setTimeout for it to call it at a later time:

setTimeout(createNewWindow, 0);

Note the missing parentheses. You're passing the value of createNewWindow (which is a function) to setTimeout, instead of calling it and passing its return value.

This should make the progress bar show up right away. However, if createNewWindow is a really expensive function eating lots of resources, it will still slow down your web page since all your JavaScript code is run in the same thread. In that case, you might want to consider using a Worker.

Mattias Buelens
  • 19,609
  • 4
  • 45
  • 51
  • This is a great catch, thanks! Unfortunately it still doesn't get that progress to show up properly... probably because it is as you mention on the same thread. However, I only see examples of workers that take a URL to a js file? Is there a way to create a new Worker with a function? Maybe just as easy as `new Worker(createNewWindow)`? – Nicros Apr 05 '13 at 23:33