Closed MixaMega closed 1 year ago
Hi @MixaMega,
how to implement clearInterval
Here's an initial attempt at a decent timeout and interval implementation. We'll skip input validation for now.
First, we'll need a .NET timer that can call a script function:
public sealed class TimerImpl {
private Timer _timer;
private Func<double> _callback = () => Timeout.Infinite;
public void Initialize(dynamic callback) => _callback = () => (double)callback();
public void Schedule(double delay) {
if (delay < 0) {
if (_timer != null) {
_timer.Dispose();
_timer = null;
}
} else {
if (_timer == null) _timer = new Timer(_ => Schedule(_callback()));
_timer.Change(TimeSpan.FromMilliseconds(delay), Timeout.InfiniteTimeSpan);
}
}
}
Now let's set up the script code:
dynamic setup = engine.Evaluate(@"(impl => {
let queue = [], nextId = 0;
const maxId = 1000000000000, getNextId = () => nextId = (nextId % maxId) + 1;
const add = entry => {
const index = queue.findIndex(element => element.due > entry.due);
index >= 0 ? queue.splice(index, 0, entry) : queue.push(entry);
}
function set(periodic, func, delay) {
const id = getNextId(), now = Date.now(), args = [...arguments].slice(3);
add({ id, periodic, func: () => func(...args), delay, due: now + delay });
impl.Schedule(queue[0].due - now);
return id;
};
function clear(id) {
queue = queue.filter(entry => entry.id != id);
impl.Schedule(queue.length > 0 ? queue[0].due - Date.now() : -1);
};
globalThis.setTimeout = set.bind(undefined, false);
globalThis.setInterval = set.bind(undefined, true);
globalThis.clearTimeout = globalThis.clearInterval = clear.bind();
impl.Initialize(() => {
const now = Date.now();
while ((queue.length > 0) && (now >= queue[0].due)) {
const entry = queue.shift();
if (entry.periodic) add({ ...entry, due: now + entry.delay });
entry.func();
}
return queue.length > 0 ? queue[0].due - now : -1;
});
})");
setup(new TimerImpl());
And now, a quick test:
engine.AddHostType(typeof(Console));
engine.AddHostObject("done", new ManualResetEventSlim());
engine.Execute(@"
const id = setInterval(() => Console.WriteLine('Hello, world!'), 1000);
setTimeout(() => {
clearInterval(id);
Console.Write('Exiting in 5 seconds...');
setTimeout(() => done.Set(), 5000);
}, 5500);
");
engine.Script.done.Wait();
Console.WriteLine(" Bye!");
is it possible to run typescript
Sure, but you'll have to use tsc
to convert your TypeScript code to JavaScript first.
Good luck!
There are a few issues that have been about setInterval, but none of them show how to implement clearInterval
Also another question, is it possible to run typescript