diff options
| author | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:26:46 -0700 |
|---|---|---|
| committer | Pinapelz <yukais@pinapelz.com> | 2025-06-28 17:43:56 -0700 |
| commit | e4fa1e69e7ebfb627c7198fd1a9881e9327ec4d4 (patch) | |
| tree | 06284a538a6008eca75051399e47db4e5d50301c /node_modules/rxjs/src/internal/observable/timer.ts | |
initial commit: scaffolding
Diffstat (limited to 'node_modules/rxjs/src/internal/observable/timer.ts')
| -rw-r--r-- | node_modules/rxjs/src/internal/observable/timer.ts | 186 |
1 files changed, 186 insertions, 0 deletions
diff --git a/node_modules/rxjs/src/internal/observable/timer.ts b/node_modules/rxjs/src/internal/observable/timer.ts new file mode 100644 index 0000000..dcc2745 --- /dev/null +++ b/node_modules/rxjs/src/internal/observable/timer.ts @@ -0,0 +1,186 @@ +import { Observable } from '../Observable'; +import { SchedulerLike } from '../types'; +import { async as asyncScheduler } from '../scheduler/async'; +import { isScheduler } from '../util/isScheduler'; +import { isValidDate } from '../util/isDate'; + +/** + * Creates an observable that will wait for a specified time period, or exact date, before + * emitting the number 0. + * + * <span class="informal">Used to emit a notification after a delay.</span> + * + * This observable is useful for creating delays in code, or racing against other values + * for ad-hoc timeouts. + * + * The `delay` is specified by default in milliseconds, however providing a custom scheduler could + * create a different behavior. + * + * ## Examples + * + * Wait 3 seconds and start another observable + * + * You might want to use `timer` to delay subscription to an + * observable by a set amount of time. Here we use a timer with + * {@link concatMapTo} or {@link concatMap} in order to wait + * a few seconds and start a subscription to a source. + * + * ```ts + * import { of, timer, concatMap } from 'rxjs'; + * + * // This could be any observable + * const source = of(1, 2, 3); + * + * timer(3000) + * .pipe(concatMap(() => source)) + * .subscribe(console.log); + * ``` + * + * Take all values until the start of the next minute + * + * Using a `Date` as the trigger for the first emission, you can + * do things like wait until midnight to fire an event, or in this case, + * wait until a new minute starts (chosen so the example wouldn't take + * too long to run) in order to stop watching a stream. Leveraging + * {@link takeUntil}. + * + * ```ts + * import { interval, takeUntil, timer } from 'rxjs'; + * + * // Build a Date object that marks the + * // next minute. + * const currentDate = new Date(); + * const startOfNextMinute = new Date( + * currentDate.getFullYear(), + * currentDate.getMonth(), + * currentDate.getDate(), + * currentDate.getHours(), + * currentDate.getMinutes() + 1 + * ); + * + * // This could be any observable stream + * const source = interval(1000); + * + * const result = source.pipe( + * takeUntil(timer(startOfNextMinute)) + * ); + * + * result.subscribe(console.log); + * ``` + * + * ### Known Limitations + * + * - The {@link asyncScheduler} uses `setTimeout` which has limitations for how far in the future it can be scheduled. + * + * - If a `scheduler` is provided that returns a timestamp other than an epoch from `now()`, and + * a `Date` object is passed to the `dueTime` argument, the calculation for when the first emission + * should occur will be incorrect. In this case, it would be best to do your own calculations + * ahead of time, and pass a `number` in as the `dueTime`. + * + * @param due If a `number`, the amount of time in milliseconds to wait before emitting. + * If a `Date`, the exact time at which to emit. + * @param scheduler The scheduler to use to schedule the delay. Defaults to {@link asyncScheduler}. + */ +export function timer(due: number | Date, scheduler?: SchedulerLike): Observable<0>; + +/** + * Creates an observable that starts an interval after a specified delay, emitting incrementing numbers -- starting at `0` -- + * on each interval after words. + * + * The `delay` and `intervalDuration` are specified by default in milliseconds, however providing a custom scheduler could + * create a different behavior. + * + * ## Example + * + * ### Start an interval that starts right away + * + * Since {@link interval} waits for the passed delay before starting, + * sometimes that's not ideal. You may want to start an interval immediately. + * `timer` works well for this. Here we have both side-by-side so you can + * see them in comparison. + * + * Note that this observable will never complete. + * + * ```ts + * import { timer, interval } from 'rxjs'; + * + * timer(0, 1000).subscribe(n => console.log('timer', n)); + * interval(1000).subscribe(n => console.log('interval', n)); + * ``` + * + * ### Known Limitations + * + * - The {@link asyncScheduler} uses `setTimeout` which has limitations for how far in the future it can be scheduled. + * + * - If a `scheduler` is provided that returns a timestamp other than an epoch from `now()`, and + * a `Date` object is passed to the `dueTime` argument, the calculation for when the first emission + * should occur will be incorrect. In this case, it would be best to do your own calculations + * ahead of time, and pass a `number` in as the `startDue`. + * @param startDue If a `number`, is the time to wait before starting the interval. + * If a `Date`, is the exact time at which to start the interval. + * @param intervalDuration The delay between each value emitted in the interval. Passing a + * negative number here will result in immediate completion after the first value is emitted, as though + * no `intervalDuration` was passed at all. + * @param scheduler The scheduler to use to schedule the delay. Defaults to {@link asyncScheduler}. + */ +export function timer(startDue: number | Date, intervalDuration: number, scheduler?: SchedulerLike): Observable<number>; + +/** + * @deprecated The signature allowing `undefined` to be passed for `intervalDuration` will be removed in v8. Use the `timer(dueTime, scheduler?)` signature instead. + */ +export function timer(dueTime: number | Date, unused: undefined, scheduler?: SchedulerLike): Observable<0>; + +export function timer( + dueTime: number | Date = 0, + intervalOrScheduler?: number | SchedulerLike, + scheduler: SchedulerLike = asyncScheduler +): Observable<number> { + // Since negative intervalDuration is treated as though no + // interval was specified at all, we start with a negative number. + let intervalDuration = -1; + + if (intervalOrScheduler != null) { + // If we have a second argument, and it's a scheduler, + // override the scheduler we had defaulted. Otherwise, + // it must be an interval. + if (isScheduler(intervalOrScheduler)) { + scheduler = intervalOrScheduler; + } else { + // Note that this *could* be negative, in which case + // it's like not passing an intervalDuration at all. + intervalDuration = intervalOrScheduler; + } + } + + return new Observable((subscriber) => { + // If a valid date is passed, calculate how long to wait before + // executing the first value... otherwise, if it's a number just schedule + // that many milliseconds (or scheduler-specified unit size) in the future. + let due = isValidDate(dueTime) ? +dueTime - scheduler!.now() : dueTime; + + if (due < 0) { + // Ensure we don't schedule in the future. + due = 0; + } + + // The incrementing value we emit. + let n = 0; + + // Start the timer. + return scheduler.schedule(function () { + if (!subscriber.closed) { + // Emit the next value and increment. + subscriber.next(n++); + + if (0 <= intervalDuration) { + // If we have a interval after the initial timer, + // reschedule with the period. + this.schedule(undefined, intervalDuration); + } else { + // We didn't have an interval. So just complete. + subscriber.complete(); + } + } + }, due); + }); +} |
