Skip to content

Instantly share code, notes, and snippets.

@salomvary
Created November 27, 2014 17:55
Show Gist options
  • Save salomvary/5a295d32e0868ffde42a to your computer and use it in GitHub Desktop.
Save salomvary/5a295d32e0868ffde42a to your computer and use it in GitHub Desktop.
setTimeout for Nashorn
// Adopted from here: https://gist.github.com/bripkens/8597903
// Makes ES7 Promises polyfill work on Nashorn https://github.com/jakearchibald/es6-promise
// (Haven't verified how correct it is, use with care)
(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 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();
}
}, millis);
return function() {
onTaskFinished();
canceled = true;
};
};
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);
@edwardalee
Copy link

This implementation looks incorrect to me. The java Timer.schedule() function invokes the specified function in a separate thread. This will result in JavaScript running in more than one concurrent thread, which creates race conditions, and violates the key JavaScript contract of asynchronous atomic callbacks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment