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