19

its a server side Javascript (rhino engine), so setTimeout is not available. how to run a function asynchronously?

dark_ruby
  • 7,646
  • 7
  • 32
  • 57

3 Answers3

42

You can use java.util.Timer and java.util.TimerTask to roll your own set/clear Timeout and set/clear Interval functions:

var setTimeout,
    clearTimeout,
    setInterval,
    clearInterval;

(function () {
    var timer = new java.util.Timer();
    var counter = 1; 
    var ids = {};

    setTimeout = function (fn,delay) {
        var id = counter++;
        ids[id] = new JavaAdapter(java.util.TimerTask,{run: fn});
        timer.schedule(ids[id],delay);
        return id;
    }

    clearTimeout = function (id) {
        ids[id].cancel();
        timer.purge();
        delete ids[id];
    }

    setInterval = function (fn,delay) {
        var id = counter++; 
        ids[id] = new JavaAdapter(java.util.TimerTask,{run: fn});
        timer.schedule(ids[id],delay,delay);
        return id;
    }

    clearInterval = clearTimeout;

})()
Weston C
  • 3,642
  • 2
  • 25
  • 31
  • 1
    Whit your code snippet, i was able to run Jasmine tests inside Rhino without the need of EnvJS. Thanks! – Gian Marco May 28 '11 at 15:25
  • I wish I could give you 100 upvotes, very awesome. Thanks so much. – Upgradingdave Aug 12 '11 at 17:03
  • 2
    Awesome. Thanks! To be fully compatibile with browsers, you need to handle omission of delay as well. MDN says that the minium delay as per the HTML5 spec is 4ms, so add the following: if (delay == null) { delay = 4; } – Brandon Bloom Apr 20 '12 at 10:08
  • @DaveParoulek You can give a bounty to Weston ;) – Stephan Feb 16 '14 at 17:40
  • 3
    **NOTA:** Rhino 1.7R4 has a bug that prevents the code in this answer to run. Either downgrade to 1.7R3 or use a newer version. (Check this discussion for details on newer versions: https://groups.google.com/d/msg/mozilla-rhino/6vvcjg_7NNU/XnWEPEyfcfwJ) – Stephan Feb 16 '14 at 18:47
  • 4
    @Alex, I created version that uses `ScheduledThreadPoolExecutor` instead of `Timer` and works in 1.7R4: https://gist.github.com/nbeloglazov/9633318 – Mikita Belahlazau Mar 19 '14 at 00:48
5

Have a look at the Multithreaded Script Execution example on the Rhino Examples page. Basically, JavaScript does not support threading directly, but you may be able to use a Java thread to achieve what you are looking for.

nwellnhof
  • 32,319
  • 7
  • 89
  • 113
Justin Ethier
  • 131,333
  • 52
  • 229
  • 284
3

Another version using ScheduledThreadPoolExecutor, compatible with Rhino 1.7R4 and proposed by @Nikita-Beloglazov:

var setTimeout, clearTimeout, setInterval, clearInterval;

(function () {
    var executor = new java.util.concurrent.Executors.newScheduledThreadPool(1);
    var counter = 1;
    var ids = {};

    setTimeout = function (fn,delay) {
        var id = counter++;
        var runnable = new JavaAdapter(java.lang.Runnable, {run: fn});
        ids[id] = executor.schedule(runnable, delay, 
            java.util.concurrent.TimeUnit.MILLISECONDS);
        return id;
    }

    clearTimeout = function (id) {
        ids[id].cancel(false);
        executor.purge();
        delete ids[id];
    }

    setInterval = function (fn,delay) {
        var id = counter++;
        var runnable = new JavaAdapter(java.lang.Runnable, {run: fn});
        ids[id] = executor.scheduleAtFixedRate(runnable, delay, delay, 
            java.util.concurrent.TimeUnit.MILLISECONDS);
        return id;
    }

    clearInterval = clearTimeout;

})()

Reference: https://gist.github.com/nbeloglazov/9633318

Community
  • 1
  • 1
Stephan
  • 41,764
  • 65
  • 238
  • 329