Created
November 27, 2014 17:55
-
-
Save salomvary/5a295d32e0868ffde42a to your computer and use it in GitHub Desktop.
setTimeout for Nashorn
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.