1

Im using casperjs, im trying to get the content of a website that changes its values using websockets. To accomplish this, instead of adding an event listener to each value, I just want to crawl the whole website every 10 seconds.

I have the following code:

casper.waitForResource("http://website.com",function() {
 getPrices(casper);
});

Inside getPrices, I'm able to scrap the values, and at the end i have the following lines:

setTimeout(getPrices(casper),5000);

The problem is that I dont know why casper ignores the timeout. It just calls it without sleeping. On the other hand, I dont think that this is the greatest solution, since its recursive and in the long run, it will end up with a memory stack.

How can i accomplish this?

Thanks!

HiDeoo
  • 10,353
  • 8
  • 47
  • 47
gabriel mellace
  • 229
  • 5
  • 15

1 Answers1

3

You are calling getPrices(casper) immediately and then passing that return value to setTimeout(), thus it doesn't wait for the timer to fire before calling the function.

Your statement of this:

setTimeout(getPrices(casper),5000);

is like this:

var temp = getPrices(casper);
setTimeout(temp, 5000);

As you can see, that calls the function immediately and passes some return value to setTimeout() which is not what you want.

To fix it, change to either one of these:

// pass anonymous stub function
setTimeout(function() {
    getPrices(casper);
},5000);

// use .bind() to create temporary function with the casper parameter bound to it
setTimeout(getPrices.bind(null, casper), 5000);

Calling a function repeatedly from a setTimeout() is not actually recursive. The stack completely unwinds before the setTimeout() fires so there is no stack build up.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • wow! thanks for that fast reply, i tried your solution and now its being called again, but im watching that the first time it executes, ok, it prints it 1 time, the next time in prints the array two times, and so on until its always printing. On the other part, could you explain me what you just did? what is that bind(null,casper) ? thanks! – gabriel mellace Jul 17 '16 at 04:53
  • @gabrielmellace - You can read about `.bind()` [here on MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind). – jfriend00 Jul 17 '16 at 04:54
  • @gabrielmellace - I don't know what "prints the array two times" means. There's nothing related to that in your question. – jfriend00 Jul 17 '16 at 04:55
  • my bad, just read that you answer "change to either ONE of these", now its working fine (: thanks!! – gabriel mellace Jul 17 '16 at 04:56
  • im waiting for the time to mark the answer as correct, but i have one doubt, this method will not produce a memory leak on the long run? is there another way of doing it? – gabriel mellace Jul 17 '16 at 05:06
  • @gabrielmellace - The code I've shown you will not produce a memory leak. I can't see the rest of your code to know that calling `getPrices()` repeatedly will or won't have a leak associated with it. You'd have to show all that code for us to have any idea on that. There are lots of ways to call something repeatedly. You can use a `setInterval()` too. – jfriend00 Jul 17 '16 at 05:50