Read my book

I wrote books about Webpack and React. Check them out!

Thursday, November 18, 2010

Setting Up a Progress Dialog in JavaScript

Setting up a blocking progress dialog ought to be easy. It should prevent the user from doing nasty things while you are processing. In principle all you should need to do is to open up a dialog, process and close the dialog once you are done.

Unfortunately things are not quite that simple in JavaScript due to its single threaded nature. It takes a small trick to work past its limitations as you shall see.

Note that in this post I presume that the processing function is entirely on the client side. In case you are dealing with a server via AJAX, you might want to do things a bit differently.

Initial Attempt


My initial attempt at solving the problem was something along this:



You can bet it won't work! The dialog shows up only after the processing has been done. This is clearly not behavior we are after.

Apparently the JavaScript interpreter does not give any processing time to the dialog at all during the execution. As a result I thought it might make sense to catch dialog show via some suitable mutation event.

I didn't bother exploring the idea further as mutation events are apparently a bit badly supported across browsers. Particularly this WebKit bug looked nasty.

Fortunately there's a proper solution for this problem. All we need to do is to make sure our processing function is executed in a smarter manner. Let's see how to do this next.

Solution


Here's the solution I came up with:



As you can see all I had to do was to exploit JavaScript's timer mechanism a bit. This ensures that the processing function is executed partially. After each execution loop the interpreter will have time to update our dialog and do some other needed duties as needed.

Conclusion


I guess the main point of this post was just to highlight the usefulness of JavaScript's interval mechanism. It really came in handy this time.

Note that there's a follow-up post showing how to abstract the core idea a bit.