Ph33ly
Ph33ly

Reputation: 693

Exiting a for loop with button in Javascript

Hey I've been having a difficult time trying to get my code to recognize when a user presses a stop button to exit a loop. I know it's a threading issue but I've been trying to work around that with setTimeout/setInterval.

In my code I have a button with onclick="stop()" with the function as stop(){cancel = true;}. In my code I have a .each loop that iterates through some rows a certain amount of times (depends on the amount of check boxes checked). Each iteration calls Row(this); which, aside from some checks and getters, contains a for-loop that iterates the total length of the current row. So something like:

for (i = 0; i < row.length; i++) {      
    ajaxCallForRowSingle(row[i]);

    if (stop == true) {
        return false; }
}  

I've tried setTimeout(ajaxCallForRowSingle(row[i]),0); but I get "Syntax error label not found" which I assume is from the ajax call. Is there a work around for this? My button press always gets queued and executes after the loop.

Upvotes: 2

Views: 1612

Answers (3)

Justin Russo
Justin Russo

Reputation: 2214

Okay, here's what you need to do...

Instead of using a 'for' loop, make a function and call it recursively using, 'setTimeout' or 'setInterval'

var iRowsToProcess = row.length;
var iRowIndex = 0;
var processRows = function(){
    if (!stop){
        ajaxCallForRowSingle(row[iRowIndex]);
        iRowIndex++;
        if (iRowIndex < iRowsToProcess){
            setTimeout(processRows, 1);
        };
    };
};

setTimeout(processRows, 1);

This code will call 'processRows' recursively until all rows are processed, or until 'stop' is false. The beauty is that each, "setTimeout" call is processed asyncronously, which means, it allows the other JS code to update before it is called again. It releases the one thread that all JS code is syncronously waiting for.

Upvotes: 2

Jimmy
Jimmy

Reputation: 91

If you wanted to use setTimeout or setInterval, you'd have to wrap your ajaxCall in another function, e.g.,

setInterval(function () {
    ajaxCallForRowSingle(row[i]);
}, 0);

You can clear the interval by storing its ID as a variable, then calling clearInterval, e.g.,

var i = 0;
var id = setInterval(function () {
    ajaxCallForRowSingle(row[i]);
    i++;
    if (i >= row.length) { clearInterval(id); }
}, 0);

var stop = function () {
    clearInterval(id);
}

Upvotes: 0

Organiccat
Organiccat

Reputation: 5651

I think you're looking for a recursive function that calls itself rather than a for loop. Also, to break a for loop, I'd use "break" rather than trying to return false.

Set up a recursive function to continue calling itself until you hit the row.length you're looking for.

Upvotes: 1

Related Questions