UNPKG

@reactivex/rxjs

Version:

Reactive Extensions for modern JavaScript

117 lines 3.4 kB
import { Subscription } from '../Subscription'; export class VirtualTimeScheduler { constructor() { this.actions = []; // XXX: use `any` to remove type param `T` from `VirtualTimeScheduler`. this.active = false; this.scheduledId = null; this.index = 0; this.sorted = false; this.frame = 0; this.maxFrames = 750; } now() { return this.frame; } flush() { const actions = this.actions; const maxFrames = this.maxFrames; while (actions.length > 0) { let action = actions.shift(); this.frame = action.delay; if (this.frame <= maxFrames) { action.execute(); if (action.error) { actions.length = 0; this.frame = 0; throw action.error; } } else { break; } } actions.length = 0; this.frame = 0; } addAction(action) { const actions = this.actions; actions.push(action); actions.sort((a, b) => { if (a.delay === b.delay) { if (a.index === b.index) { return 0; } else if (a.index > b.index) { return 1; } else { return -1; } } else if (a.delay > b.delay) { return 1; } else { return -1; } }); } schedule(work, delay = 0, state) { this.sorted = false; return new VirtualAction(this, work, this.index++).schedule(state, delay); } } VirtualTimeScheduler.frameTimeFactor = 10; /** * We need this JSDoc comment for affecting ESDoc. * @ignore * @extends {Ignored} */ class VirtualAction extends Subscription { constructor(scheduler, work, index) { super(); this.scheduler = scheduler; this.work = work; this.index = index; this.calls = 0; } schedule(state, delay = 0) { if (this.isUnsubscribed) { return this; } const scheduler = this.scheduler; let action = null; if (this.calls++ === 0) { // the action is not being rescheduled. action = this; } else { // the action is being rescheduled, and we can't mutate the one in the actions list // in the scheduler, so we'll create a new one. action = new VirtualAction(scheduler, this.work, scheduler.index += 1); this.add(action); } action.state = state; action.delay = scheduler.frame + delay; scheduler.addAction(action); return this; } execute() { if (this.isUnsubscribed) { throw new Error('How did did we execute a canceled Action?'); } this.work(this.state); } unsubscribe() { const actions = this.scheduler.actions; const index = actions.indexOf(this); this.work = void 0; this.state = void 0; this.scheduler = void 0; if (index !== -1) { actions.splice(index, 1); } super.unsubscribe(); } } //# sourceMappingURL=VirtualTimeScheduler.js.map