6

I am just curious how CasperJS handles events with regards to the call stack.

Let's say we have some code:

casper.on('foo', function() {
    this.wait(60000);
    this.echo('foo');
});


casper.start('http://www.stackoverflow.com', function() {
    this.echo('start');
    this.emit('foo');
});


casper.then(function() {
    this.echo('done');
});

casper.run();

I know that then() will wait check against 3 flags: pendingWait, loadInProgress, and navigationRequested. Printing out the call stack shows the emit call to be in the function start(), so will start() not be considered finished until the event is finished? I.e. will then() wait until the event has finished

I tested this with wait of 60 seconds, and I did get the output:

start
foo
done

Though I was not sure if exceeding a certain timeout would trigger the next then().

Community
  • 1
  • 1
Kimmy_Tran
  • 140
  • 2
  • 7

1 Answers1

3

You have to keep in mind which functions are executed asynchronously. In your case the first two lines of the output are printed immediately when the page was loaded and done was printed 60 seconds later.

Things to know:

  • All then* and wait* functions will insert a step into the queue, but are themselves asynchronous.
  • casper.emit will look for the registered event handler and execute it immediately (non-asynchronous).
  • casper.echo will print something immediately (non-asynchronous).

The order of events is that in the start callback, which itself is a step function, an event is triggered and immediately executed. This executed event contains a wait call which adds a delayed step after the current one (we're still in the start callback). Then echo is executed and the current step is finished. The next step begins by waiting 60 seconds. Since no callback was passed to wait the next sheduled step is executed. This is the last step which contains echo('done').

So strictly speaking then doesn't wait for the event execution of the previous step, but in this case there was no break out of the control flow (usually done through setTimeout) and the CasperJS step processor has caught the inner wait step.

Artjom B.
  • 61,146
  • 24
  • 125
  • 222
  • Very thorough, thanks for the response! If I replaced the wait statement with some non-asynch logic that took some time, should I still expect the same output? From my understanding the start callback finishes once the last non-asynch statment finishes (even if that statement is in some event), and then() won't execute before that point. – Kimmy_Tran Jan 04 '15 at 23:47
  • 1
    Your observation is correct and the output will be the same, but the timings would be different, since the now blocking wait is before `this.echo('foo');` – Artjom B. Jan 04 '15 at 23:57