Mobilpadde
Mobilpadde

Reputation: 1881

Pause a for loop

Is it possible to pause a for loop in javascript/jquery?

I have a $.each, that runs through a 63 long array, which have a for inside, which have another for, which have yet another for in it (Makes each>for>for>for), now each of the for loops through the array, this makes 63^4 (Equals 15752961) different combinations, and that takes time...

Sooo, is it possible to pause it 2sec, at 2k combinations?

Reason why I want to pause the loop, is to unlock the UI...

Code:

var $arr = ["","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"],
len = $arr.length,
l = 0,
$("body").delay(1000).show(0, function(){
    $.each($arr, function(index, val){ // 63
        for(var i = 0; i < len; i++){ // 3969
            for(var j = 0; j < len; j++){ // 250047
                for(var k = 0; k < len; k++){ // 15752961
                    thing = val+i+j+k;
                    l++;
                    $("#loading").text(l+"/15752961");
                    console.log(l+"/15752961");
                    $("<div>"+thing+"</div><br />").prependTo("body");                                  
                }
            }
        }
    })
})

Ps. If someone think, they could clear up my question, please do so :D

/* EDIT */ If I try to run this server side, I get a server error, both if I use foreach or for

$smaa = range("a","z");
$store = range("A","Z");
$tal = range("0","9");
$arr = array_merge($smaa, $store, $tal);

for($i = 0; $i < $count; $i++){ // 62
    for($j = 0; $j < $count; $j++){ // 3844
        for($k = 0; $k < $count; $k++){ // 238328
            for($l = 0; $l < $count; $l++){ // 14776336
                $finish[] = $arr[$i].$arr[$j].$arr[$k].$arr[$l];
            }
            $finish[] = $arr[$i].$arr[$j].$arr[$k];
        }
        $finish[] = $arr[$i].$arr[$j];
    }
$finish[] = $arr[$i];
}

foreach($arr as $first){ // 62
    $finish[] = $first;
    foreach($arr as $second){ // 3844
        $finish[] = $first.$second;
        foreach($arr as $third){ // 238328
            $finish[] = $first.$second.$third;
            foreach($arr as $fourth){ // 14776336
                $finish[] = $first.$second.$third.$fourth;
            }
        }
    }
}

Please note, that I don't use both on the same time

Upvotes: 0

Views: 836

Answers (3)

Fresheyeball
Fresheyeball

Reputation: 30015

This is untested, but hopefully you will get the idea. Truthfully, this is something you probably should be handling on the server-side, or doing once and storing the output in the code.

var $arr = ["","a","b","c","d","e","f","g","h","i","j","k","l","m","n","o","p","q","r","s","t","u","v","w","x","y","z","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4","5","6","7","8","9"],
len = $arr.length,
l = 0,
paused = false,
writer = '',
pauseAt = 2000;

$("body").delay(1000).show(0, function(){

    function killForTwoSeconds(){ //function to timeout loop
         paused = true; //set to true to kill loop
         $('body').append(writer); //write to body only on pause (fewer writes to dom = faster script)
         setTimeout(function(){ // wait for 2 seconds
              paused = false;
              loopIt(); // re-run loop
         },2000);
    }

    function loopIt(){
        $.each($arr, function(index, val){ 
            for(var i = l; i < len; i++){ 
                for(var j = l; j < len; j++){ //loops now start at l instead of 0 so when loop restarts it restarts at the right place
                    for(var k = l; k < len; k++){ 
                        if(l % pauseAt === 0){ // if l is divisible by 2000 kill 
                            killForTwoSeconds();
                        }
                        if(!paused){ //if not paused add item to writer
                            thing = val+i+j+k;
                            l++;
                            $("#loading").text(l+"/15752961");
                            console.log(l+"/15752961");
                            writer = "<div>"+thing+"</div><br />";                                  
                        }else if(index === len-1 && k === len-1){
                            $('body').append(writer); //final write
                        }else{
                            return false; // if paused return false
                        }
                    }
                }
            }
        });
    }
});

Upvotes: 1

gdoron
gdoron

Reputation: 150253

No, it's no possible to "pause" a for loop, and anyway it will not make it faster.

Don't use it here, but take a look at window.setTimeout(fn, delay)

Upvotes: 1

Niet the Dark Absol
Niet the Dark Absol

Reputation: 324610

No.

However, you can use something like this:

(function() {
    var i=0, j=0, k=0, timer;
    timer = setInterval(function() {
        // loop body here
        k++;
        if( k >= max_k) {
            k = 0;
            j++;
            if( j >= max_j) {
                j = 0;
                i++;
                if( i >= max_i) {
                    clearInterval(timer);
                }
            }
        }
    },1);
})();

I'm not sure how to integrate that with $.each, you may have to do it in plain JavaScript. But this code will basically run the loop as fast as possible while still redrawing.

Upvotes: 1

Related Questions