1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-12-22 07:14:47 -05:00

Adds setInterval, clearInterval, clearTimeout.

This commit is contained in:
Parsa Ghadimi 2018-05-23 23:23:41 +04:30 committed by Ryan Dahl
parent 3171ba4c3f
commit cb222ceb22
7 changed files with 126 additions and 19 deletions

View file

@ -1,4 +1,4 @@
import { setTimeout } from "./timers";
import * as timer from "./timers";
// If you use the eval function indirectly, by invoking it via a reference
// other than eval, as of ECMAScript 5 it works in the global scope rather than
@ -14,7 +14,10 @@ export const _global = globalEval("this");
_global["window"] = _global; // Create a window object.
import "./url";
_global["setTimeout"] = setTimeout;
_global["setTimeout"] = timer.setTimeout;
_global["setInterval"] = timer.setInterval;
_global["clearTimeout"] = timer.clearTimer;
_global["clearInterval"] = timer.clearTimer;
const print = V8Worker2.print;

View file

@ -16,6 +16,7 @@ message Msg {
ExitMsg exit = 14;
TimerStartMsg timer_start = 15;
TimerReadyMsg timer_ready = 16;
TimerClearMsg timer_clear = 17;
}
}
@ -60,3 +61,5 @@ message TimerReadyMsg {
optional int32 id = 1;
optional bool done = 2;
}
message TimerClearMsg { optional int32 id = 1; }

View file

@ -3,3 +3,9 @@ setTimeout(function() {
}, 10);
console.log("Hello");
const id = setTimeout(function() {
console.log("Not printed");
}, 10000);
clearTimeout(id);

7
testdata/010_set_interval.ts vendored Normal file
View file

@ -0,0 +1,7 @@
const id = setInterval(function() {
console.log("test")
}, 200);
setTimeout(function() {
clearInterval(id)
}, 500)

2
testdata/010_set_interval.ts.out vendored Normal file
View file

@ -0,0 +1,2 @@
test
test

View file

@ -5,6 +5,16 @@ import (
"time"
)
type Timer struct {
Id int32
Done bool
Cleared bool
Interval bool
Duration int32 // In milliseconds
}
var timers = make(map[int32]*Timer)
func InitTimers() {
Sub("timers", func(buf []byte) []byte {
msg := &Msg{}
@ -12,28 +22,62 @@ func InitTimers() {
switch msg.Payload.(type) {
case *Msg_TimerStart:
payload := msg.GetTimerStart()
return HandleTimerStart(*payload.Id, *payload.Interval,
*payload.Duration)
timers[*payload.Id] = &Timer{
Id: *payload.Id,
Done: false,
Interval: *payload.Interval,
Duration: *payload.Duration,
Cleared: false,
}
timers[*payload.Id].StartTimer()
return nil
case *Msg_TimerClear:
payload := msg.GetTimerClear()
// TODO maybe need mutex here.
timer := timers[*payload.Id]
timer.Clear()
return nil
default:
panic("[timers] Unexpected message " + string(buf))
}
})
}
func HandleTimerStart(id int32, interval bool, duration int32) []byte {
func (t *Timer) Clear() {
if !t.Cleared {
wg.Done()
t.Cleared = true
delete(timers, t.Id)
}
t.Done = true
}
func (t *Timer) StartTimer() {
wg.Add(1)
go func() {
defer wg.Done()
time.Sleep(time.Duration(duration) * time.Millisecond)
payload, err := proto.Marshal(&Msg{
Payload: &Msg_TimerReady{
TimerReady: &TimerReadyMsg{
Id: &id,
defer t.Clear()
for {
time.Sleep(time.Duration(t.Duration) * time.Millisecond)
if !t.Interval {
t.Done = true
}
pubMsg(&Msg{
Payload: &Msg_TimerReady{
TimerReady: &TimerReadyMsg{
Id: &t.Id,
Done: &t.Done,
},
},
},
})
check(err)
Pub("timers", payload)
})
if t.Done {
return
}
}
}()
return nil
}
func pubMsg(msg *Msg) {
payload, err := proto.Marshal(msg)
check(err)
Pub("timers", payload)
}

View file

@ -4,12 +4,14 @@ import * as dispatch from "./dispatch";
let nextTimerId = 1;
// tslint:disable-next-line:no-any
type TimerCallback = (...args: any[]) => void;
export type TimerCallback = (...args: any[]) => void;
interface Timer {
id: number;
cb: TimerCallback;
interval: boolean;
// tslint:disable-next-line:no-any
args: any[];
duration: number; // milliseconds
}
@ -23,17 +25,26 @@ function onMessage(payload: Uint8Array) {
const msg = pb.Msg.decode(payload);
const { id, done } = msg.timerReady;
const timer = timers.get(id);
timer.cb();
if (!timer) {
return;
}
timer.cb(...timer.args);
if (done) {
timers.delete(id);
}
}
export function setTimeout(cb: TimerCallback, duration: number): number {
export function setTimeout(
cb: TimerCallback,
duration: number,
// tslint:disable-next-line:no-any
...args: any[]
): number {
const timer = {
id: nextTimerId++,
interval: false,
duration,
args,
cb
};
timers.set(timer.id, timer);
@ -46,3 +57,34 @@ export function setTimeout(cb: TimerCallback, duration: number): number {
});
return timer.id;
}
// TODO DRY with setTimeout
export function setInterval(
cb: TimerCallback,
repeat: number,
// tslint:disable-next-line:no-any
...args: any[]
): number {
const timer = {
id: nextTimerId++,
interval: true,
duration: repeat,
args,
cb
};
timers.set(timer.id, timer);
dispatch.sendMsg("timers", {
timerStart: {
id: timer.id,
interval: true,
duration: repeat
}
});
return timer.id;
}
export function clearTimer(id: number) {
dispatch.sendMsg("timers", {
timerClear: { id }
});
}