Skip to content

Instantly share code, notes, and snippets.

@damienbutt
Forked from josmardias/setTimeout-nashorn.js
Created December 10, 2024 21:37
Show Gist options
  • Select an option

  • Save damienbutt/9e7e65ef0b305e9c5b67bb77cff387c7 to your computer and use it in GitHub Desktop.

Select an option

Save damienbutt/9e7e65ef0b305e9c5b67bb77cff387c7 to your computer and use it in GitHub Desktop.
setTimeout polyfill for Nashorn
// https://gist.github.com/josmardias/20493bd205e24e31c0a406472330515a
// at least one timeout needs to be set, larger then your code bootstrap
// or Nashorn will run forever
// preferably, put a timeout 0 after your code bootstrap
(function(context) {
'use strict';
var Timer = Java.type('java.util.Timer');
var Phaser = Java.type('java.util.concurrent.Phaser');
var timer = new Timer('jsEventLoop', false);
var phaser = new Phaser();
var timeoutStack = 0;
function pushTimeout() {
timeoutStack++;
}
function popTimeout() {
timeoutStack--;
if (timeoutStack > 0) {
return;
}
timer.cancel();
phaser.forceTermination();
}
var onTaskFinished = function() {
phaser.arriveAndDeregister();
};
context.setTimeout = function(fn, millis /* [, args...] */) {
var args = [].slice.call(arguments, 2, arguments.length);
var phase = phaser.register();
var canceled = false;
timer.schedule(function() {
if (canceled) {
return;
}
try {
fn.apply(context, args);
} catch (e) {
print(e);
} finally {
onTaskFinished();
popTimeout();
}
}, millis);
pushTimeout();
return function() {
onTaskFinished();
canceled = true;
popTimeout();
};
};
context.clearTimeout = function(cancel) {
cancel();
};
context.setInterval = function(fn, delay /* [, args...] */) {
var args = [].slice.call(arguments, 2, arguments.length);
var cancel = null;
var loop = function() {
cancel = context.setTimeout(loop, delay);
fn.apply(context, args);
};
cancel = context.setTimeout(loop, delay);
return function() {
cancel();
};
};
context.clearInterval = function(cancel) {
cancel();
};
})(this);
// (TEST) /usr/java/default/bin/jjs setTimeout-nashorn.js test.js
console.log(1)
t1 = setTimeout(function () {
console.log(4);
}, 300)
console.log(2)
t2 = setTimeout(function () {
console.log(3);
}, 200)
clearTimeout(t1)
// OUTPUT:
// 1
// 2
// 3
// (TEST) /usr/java/default/bin/jjs setTimeout-nashorn.js test2.js
console.log('start')
var i = 0;
t1 = setInterval(function () {
console.log('i-' + ++i);
}, 10)
t2 = setTimeout(function () {
clearInterval(t1)
console.log('end')
}, 100)
// OUTPUT:
// start
// i-1
// i-2
// i-3
// i-4
// i-5
// i-6
// i-7
// i-8
// end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment