| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142 | "use strict";var __extends = (this && this.__extends) || function (d, b) {    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];    function __() { this.constructor = d; }    d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());};var root_1 = require('../util/root');var Action_1 = require('./Action');/** * We need this JSDoc comment for affecting ESDoc. * @ignore * @extends {Ignored} */var AsyncAction = (function (_super) {    __extends(AsyncAction, _super);    function AsyncAction(scheduler, work) {        _super.call(this, scheduler, work);        this.scheduler = scheduler;        this.pending = false;        this.work = work;    }    AsyncAction.prototype.schedule = function (state, delay) {        if (delay === void 0) { delay = 0; }        if (this.closed) {            return this;        }        // Always replace the current state with the new state.        this.state = state;        // Set the pending flag indicating that this action has been scheduled, or        // has recursively rescheduled itself.        this.pending = true;        var id = this.id;        var scheduler = this.scheduler;        //        // Important implementation note:        //        // Actions only execute once by default, unless rescheduled from within the        // scheduled callback. This allows us to implement single and repeat        // actions via the same code path, without adding API surface area, as well        // as mimic traditional recursion but across asynchronous boundaries.        //        // However, JS runtimes and timers distinguish between intervals achieved by        // serial `setTimeout` calls vs. a single `setInterval` call. An interval of        // serial `setTimeout` calls can be individually delayed, which delays        // scheduling the next `setTimeout`, and so on. `setInterval` attempts to        // guarantee the interval callback will be invoked more precisely to the        // interval period, regardless of load.        //        // Therefore, we use `setInterval` to schedule single and repeat actions.        // If the action reschedules itself with the same delay, the interval is not        // canceled. If the action doesn't reschedule, or reschedules with a        // different delay, the interval will be canceled after scheduled callback        // execution.        //        if (id != null) {            this.id = this.recycleAsyncId(scheduler, id, delay);        }        this.delay = delay;        // If this action has already an async Id, don't request a new one.        this.id = this.id || this.requestAsyncId(scheduler, this.id, delay);        return this;    };    AsyncAction.prototype.requestAsyncId = function (scheduler, id, delay) {        if (delay === void 0) { delay = 0; }        return root_1.root.setInterval(scheduler.flush.bind(scheduler, this), delay);    };    AsyncAction.prototype.recycleAsyncId = function (scheduler, id, delay) {        if (delay === void 0) { delay = 0; }        // If this action is rescheduled with the same delay time, don't clear the interval id.        if (delay !== null && this.delay === delay && this.pending === false) {            return id;        }        // Otherwise, if the action's delay time is different from the current delay,        // or the action has been rescheduled before it's executed, clear the interval id        return root_1.root.clearInterval(id) && undefined || undefined;    };    /**     * Immediately executes this action and the `work` it contains.     * @return {any}     */    AsyncAction.prototype.execute = function (state, delay) {        if (this.closed) {            return new Error('executing a cancelled action');        }        this.pending = false;        var error = this._execute(state, delay);        if (error) {            return error;        }        else if (this.pending === false && this.id != null) {            // Dequeue if the action didn't reschedule itself. Don't call            // unsubscribe(), because the action could reschedule later.            // For example:            // ```            // scheduler.schedule(function doWork(counter) {            //   /* ... I'm a busy worker bee ... */            //   var originalAction = this;            //   /* wait 100ms before rescheduling the action */            //   setTimeout(function () {            //     originalAction.schedule(counter + 1);            //   }, 100);            // }, 1000);            // ```            this.id = this.recycleAsyncId(this.scheduler, this.id, null);        }    };    AsyncAction.prototype._execute = function (state, delay) {        var errored = false;        var errorValue = undefined;        try {            this.work(state);        }        catch (e) {            errored = true;            errorValue = !!e && e || new Error(e);        }        if (errored) {            this.unsubscribe();            return errorValue;        }    };    /** @deprecated internal use only */ AsyncAction.prototype._unsubscribe = function () {        var id = this.id;        var scheduler = this.scheduler;        var actions = scheduler.actions;        var index = actions.indexOf(this);        this.work = null;        this.state = null;        this.pending = false;        this.scheduler = null;        if (index !== -1) {            actions.splice(index, 1);        }        if (id != null) {            this.id = this.recycleAsyncId(scheduler, id, null);        }        this.delay = null;    };    return AsyncAction;}(Action_1.Action));exports.AsyncAction = AsyncAction;//# sourceMappingURL=AsyncAction.js.map
 |