Reputation: 2300
I have copied this example in CasperJS.
How would I implement a 'continue' command in combination?
casper.then(function() {
var current = 1;
var end = 4;
var something = true;
for (;current < end;) {
(function(cntr) {
casper.thenOpen('about:blank', function() {
this.echo('loop number: '+ cntr);
});
casper.then(function(){
if (something) {
continue; // ERROR: 'continue' is only valid inside a loop statement
}
});
casper.then(function(){
this.echo('this still gets printed');
});
})(current);
current++;
}
});
I'm getting a 'only valid inside a loop' error but... it is inside a loop?
Upvotes: 2
Views: 1128
Reputation: 61892
All casper.then*
and casper.wait*
functions are asynchronous. The step functions that you pass into them are in fact executed after the loop has finished. Therefore you cannot use continue
to jump to the next iteration.
You can however nest all step functions, which achieves what you expect:
casper.then(function() {
var current = 1;
var end = 4;
var something = true;
while(current < end) {
(function(cntr) {
casper.thenOpen('about:blank', function() {
this.echo('loop number: '+ cntr);
});
casper.then(function(){
if (something) {
return; // this replaced `continue`
}
// more synchronous code
this.then(function(){
this.echo('this still gets printed');
});
});
})(current);
current++;
}
});
It's a bit shorter at the expense of one additional indentation level.
Upvotes: 2
Reputation: 2300
This solution works but I'm not very happy about it. Added an if/else to every casper.then section with a global skip variable. As soon as a continue condition is met all following casper.thens are effectively skipped. Skip is reset at the start of each loop.
casper.start();
casper.then(function() {
var current = 1;
var end = 4;
var skip;
for (;current < end;) {
(function(cntr) {
casper.thenOpen('about:blank', function() {
this.echo('loop number: '+ cntr);
skip = false;
});
casper.then(function(){
if (skip) {
this.echo('skipping');
}
else {
// put all code here that was in casper.then
this.echo('proceed as normal');
skip = true;
}
});
casper.then(function(){
if (skip) {
this.echo('skipping');
}
else {
// put all code here that was in casper.then
this.echo('this no longer gets printed');
}
});
})(current);
current++;
}
});
Upvotes: 1
Reputation: 92274
Once you are inside an inner function (you actually have two levels, the IIFE around the body of the loop and the function you're passing to thenOpen
), you're no longer in the scope of the loop.
Also, the functions that are passed to casper.then
and casper.thenOpen
execute asynchronously (but in order). If you want to affect the order, you have to check values from within those functions.
casper.then(function() {
var current = 1;
var end = 4;
var something = true;
var shouldContinue = false;
for (;current < end;) {
(function(cntr) {
casper.thenOpen('about:blank', function() {
shouldContinue = false;
this.echo('loop number: '+ cntr);
});
})(current, s);
(function(cntr) {
casper.then(function(){
if (something) {
shouldContinue = true;
}
});
})(current);
(function(cntr) {
if (shouldContinue) {
return;
}
casper.then(function(){
this.echo('this still gets printed');
});
})(current);
current++;
}
});
Upvotes: 1
Reputation: 24531
It is not inside the loop. When you isolate your scope with an anonymous function you lose the "loop scope" reference, so your continue does not know where the loop is. Although you can use closures (variables outside of the functions scope), you can't refer an outside loop...
See in the console:
for (var i=0;i<10;i++) continue;
works like a charm, when
for (var i=0;i<10;i++) (function(){ continue; })();
does not work because the loop reference is lost.
How to deal with that? Just return a result from your function, e.g.
for (var i=0;i<10;i++) {
if ((function(){ return i === 3; })()) {
console.log('continued');
continue;
}
}
Upvotes: 1