Search code examples
phpjavascriptrhinoenvjs

EnvJS/Rhino, setTimeout() not working


I currently set up EnvJS on my system (installed from here). My end goal is to load a page let it's javascript process for a few seconds, and then read the dom to get the information of interest. However I can not get setTimeout() to work to save my life (Or JQuery for that matter).

I have a php script that starts the process:

...
$ENVJS_PATH = "/var/www/project/src/envjs";
$RHINO_JAR = "rhino/js.jar";
$INIT_SCRIPT = "init.js";
$output = shell_exec("java -jar $ENVJS_PATH/$RHINO_JAR -opt -1 $ENVJS_PATH/$INIT_SCRIPT");
echo "Response from javascript:<br/> $output";
...

the init.js file looks like:

load('/var/www/project/src/envjs/dist/env.rhino.js');
print("Loaded env.rhino.js<br/>");

// temporarily commented out
//var url = "http://www.ken-soft.com";
//window.location = url;
//print("<br/>Loaded "+url+"<br/>");

// Problem starts here
var runAfterPause=function() {
  print("got here..."); // never gets called
  print(document.getElementById('some_id').innerHTML);
}
setTimeout(runAfterPause, 3000); //wait three seconds before continuing
// i have also tried setTimeout("runAfterPause()", 3000);
print("<br/>End<br/>");

Any knowledge on this would be much appreciated. Thanks.


Solution

  • Try env.rhino.1.2.js - and if the server OS hosting rhino is Ubuntu, then try sudo apt-get install rhino -- and call rhino -opt -1 ... instead of java -jar ...

    Seems to run like this for me on Ubuntu 11.04, when ran directly on the shell - not sure if PHP's shell_exec may influence things or not..

    EDIT: Indeed it is not really working; I looked through the source a bit, and could see that setTimeout relies on Timer.prototype.start = function(){};, which is apparently empty. Browsing further, the only thing that seems to deal with timing is Envjs.wait() - and using that, I can finally get a sort of a timed loop; however, note that it seems to be strictly single-threaded (synchronous) now:

    print("loading " + 1.2);
    load('env.rhino.1.2.js'); // takes a while ...
    print("loaded " + 1.2);
    console.log(window);
    
    var c=0;
    function timedCount() // like this, when setTimeout calls a string!
    {
      c=c+1;
      print("c=" + c);
    
      if (c<10) // make a limit for the run of script:
      {
        var t;
        //~ t=window.setTimeout(timedCount(),100); // TypeError: fn is not a function, it is undefined.
        t=window.setTimeout("timedCount()",1000); // must have `t=...` - else it locks on return even w/ wait(0)!
        Envjs.wait(); // waits, but "timer error  undefined   TypeError: fn is not a function, it is undefined." if setTimout doesn't call string; wait(0) exits immediately
      } else Envjs.wait(0); // "reset": execute all timers and return; else here will be left hanging from previous wait()
    }
    
    
    
    // main:
    
    timedCount();
    //~ eval("timedCount()", null); // works the same
    
    print("after timedCount()");
    

    ... and the results are:

    $ sudo apt-get install rhino
    $ wget https://github.com/thatcher/env-js
    
    $ rhino -opt -1 test.js
    loading 1.2
    [  Envjs/1.6 (Rhino; U; Linux i386 2.6.38-11-generic; en-US; rv:1.7.0.rc2) Resig/20070309 PilotFish/1.2.13  ]
    loaded 1.2
    [Window]
    a
    c=1
    c=2
    c=3
    c=4
    c=5
    c=6
    c=7
    c=8
    c=9
    c=10
    after timedCount()
    

    If I recall correctly, in a browser setInterval is asynchronous/multithreaded - indeed, in a browser JavaScript Shell 1.4, the almost same code:

    var c=0;
    function timedCount() 
    {
      c=c+1;
      print("c=" + c);
    
      if (c<10)  {
        var t;
        t=window.setTimeout("timedCount()",1000); 
      }
    }
    
    timedCount();
    print("after timedCount()");
    

    produces:

    c=1
    after timedCount()
    c=2
    c=3
    c=4
    c=5
    c=6
    c=7
    c=8
    c=9
    c=10