shelving
Version:
Toolkit for using data in JavaScript.
32 lines (31 loc) • 1.36 kB
JavaScript
import { Starter } from "../util/start.js";
import { DeferredSequence } from "./DeferredSequence.js";
import { IteratorSequence } from "./IteratorSequence.js";
/** Deferred sequence of values that calls a `StartCallback` when it has iterators that are iterating, and calls the corresponding `StopCallback` when all iterators have finished. */
export class LazyDeferredSequence extends DeferredSequence {
_iterating = 0;
_starter;
constructor(start) {
super();
this._starter = new Starter(start);
}
// biome-ignore lint/suspicious/useAwait: We want the method to be async but we're using `yield*` rather than `await`
async *[Symbol.asyncIterator]() {
this._starter.start(this);
this._iterating++;
try {
// Delegate to the superclass's async iterator.
// Wrap in an `IteratorSequence` because we know the superclass `AbstractSequence.prototype.[Symbol.asyncIterator]()` simply returns `this`
// `yield* this` would call this method again and cause an infinite loop.
yield* new IteratorSequence(super[Symbol.asyncIterator]());
}
finally {
this._iterating--;
if (this._iterating < 1)
this._starter.stop();
}
}
[Symbol.dispose]() {
this._starter[Symbol.dispose]();
}
}