1

So I'm building a rather complex (from my standpoint) client-sided web-app in Javascript.

What the program does basically is take a (rather huge) set of string data from the user, take a list of keywords from the user, perform a search and return an array of true/false.

Very plainly it works that way :

var userData = ["lorem ipsum", "dolor sit amet", " consectetur adipisicing"];
var userKeywords = ["et","or"];
var isMatch = false;

for (var x in userData){
    var y = 0;
    while (y<userKeywords.length && !isMatch){
    isMatch = (userData[x].match(userKeywords[y]) !== null)? true : false;
    y++;
    }
}
// That would return [true, true, true]

(that was just to give you the main idea)

Because I'm dealing with rather big quantities of data (50K ++) and keywords (~50) my program can run for a couple minutes. Whilst we know not to panic and wait when a huge program is running, my users won't...

So I wanted to give them some feedback on the execution of the program while it is running like a basic progress bar would, but I couldn't find how.

I know I could calculate the length of the task I'm asking my program to do, then increment a counter and post the result into the DOM - but wouldn't it be a problem to access the DOM in a loop ?

var userData = ["lorem ipsum", "dolor sit amet", " consectetur adipisicing"];
var userKeywords = ["et","or"];
var isMatch = false;
var myTask = userData.length * userKeywords.length ;
var myCounter = 0;

for (var x in userData){
    var y = 0;
    while (y<userKeywords.length && !isMatch){
    isMatch = (userData[x].match(userKeywords[y]) !== null)? true : false;
    y++;
    myCounter++;
    console.log("Ran " + myCounter + " calculations out of " + myTask);
    }
}

So, how can I give feedback to my user on the execution of the program ? Thanks!

clecai
  • 85
  • 1
  • 8
  • Use `setInterval` to run a function with a small delay between each invocation, and have the function perform the next step and update the progress bar. – Barmar May 05 '14 at 10:09

2 Answers2

0

I know I could calculate the length of the task I'm asking my program to do, then increment a counter and post the result into the DOM

I would go with that.

document.getElementById('output_progress').innerHTML = y + "/" + userData.length;

And if you don't want to output anything, then the best way of telling people that program is still working is with a gif loader image. That's what I usually add in my apps.

Starwave
  • 2,352
  • 2
  • 23
  • 30
  • Hey, I've run a few tests but couldn't get any satisfying result.. JQuery (or native JS getElementById for that matter) doesn't update the DOM before the function is done running. When all the data is processed the DOM is finally updated with the highest value... This occurs even though I'm using a callback function, or if I set an interval / timeout - which is odd. – clecai May 05 '14 at 15:55
0

Depending on your supported browsers, you could either go with web workers (per http://caniuse.com/#feat=webworkers IE10 is your minimum threshold), or a 'chunked' handler. Using callbacks or promises, you can pretty easily create a standard api that will support either - though the webworkers will be faster and the UI response will be smoother.

Here's a super rough example: http://plnkr.co/edit/u72tKlLR1yKvgJBsnUK9 (note that on line 5 of script.js I've disabled the web workers, as most of our browsers would use it anyway and I was hoping to show that it would work without them - just remove the && false to reenable).

Unfortunately I've been lazy and just copied and pasted your code twice. Using XHR's, you could keep your code in one spot, then pull it in with both the web worker or the run function. The 'runner' is a pretty common thing I've done in the past to give some sort of UI feedback. It takes a "chunk" of the overall task, runs it.. then stops and waits for a second before moving on to the next chunk. Usually that's enough to allow the screen to update.

Stephen
  • 5,362
  • 1
  • 22
  • 33
  • I didn't know about web workers and I will have to learn a bit more about them first - as I think this would indeed be the solution. For the time being my project has to run locally (before further validation) which doesn't allow me to use web workers (not supported by webkit locally). Thanks anyways, very helpful! – clecai May 05 '14 at 15:59
  • If you're building locally, I'd really recommend using something like https://github.com/devpaul/grunt-devserver -it's not nearly as much of a hassle to setup as Apache and let's you really stimulate a working environment. – Stephen May 05 '14 at 16:26