The JavaScript code defines an async iterable class CustumIterable parameterized over two types, which facilitates iteration over a sequence of async fetched items defined by a starting index and next index computation function. A showDogs function demonstrates its usage, iterating over dog objects asynchronously fetched by ID until undefined is returned, signaling the end of the iterable.
interface ICustomIterableParams<T, IndexType> {
index: IndexType;
nextIndex: (index: IndexType, item: T) => IndexType;
next: (index: IndexType) => Promise<T>;
}
class CustumIterable<T, K> implements AsyncIterable<T> {
private index = this.params.index;
constructor(private params: ICustomIterableParams<T, K>) {}
public [Symbol.asyncIterator](): AsyncIterator<T> {
return { next: async () => this.next() };
}
private async next(): Promise<IteratorResult<T>> {
const item = await this.params.next(this.index);
this.index = this.params.nextIndex(this.index, item);
return {
done: item === undefined,
value: item
};
}
}
/// Usage:
interface IDog {
breed: string;
age: number;
}
async function getDog(id: number): Promise<IDog> {
const dogs: IDog[] = [
{ breed: "german shepherd", age: 2 },
{ breed: "labrador", age: 4 }
];
return dogs[id] || undefined;
}
const dogIterable: AsyncIterable<IDog> = new CustumIterable<IDog, number>({
index: 0,
nextIndex: index => index + 1,
next: index => getDog(index)
});
async function showDogs(): Promise<void> {
for await (const dog of dogIterable) {
console.log(dog);
}
}
showDogs().catch(e => {
throw new Error(e);
});