Skip to content

Instantly share code, notes, and snippets.

@danielbodart
Created February 24, 2018 12:18
Show Gist options
  • Select an option

  • Save danielbodart/e9df0d03d020c00bd8e6d1566dc25932 to your computer and use it in GitHub Desktop.

Select an option

Save danielbodart/e9df0d03d020c00bd8e6d1566dc25932 to your computer and use it in GitHub Desktop.
Callback to AsyncIterator in Typescript/Javascript
/*
* Usage:
* const message: IncomingMessage = ...
* const iterator = new AsyncIteratorHandler<string>();
* message.on("data", chunk => {
* iterator.handle({value: chunk.toString(), done: false});
* });
* this.message.on("end", () => {
* iterator.handle({value: null as any, done: true})
* });
* this.message.on("error", error => {
* iterator.handle(error)
* });
* return iterator;
*/
type StateHandler = [Function, Function];
type IteratorState<T> = StateHandler | IteratorResult<T> | Error;
function isStateHandler<T>(state: IteratorState<T>): state is StateHandler {
return Array.isArray(state);
}
function consume<T>(state: IteratorResult<T> | Error, [resolve, reject]:[Function, Function]){
if (state instanceof Error) reject(state);
else resolve(state);
}
class AsyncIteratorHandler<T> implements AsyncIterator<T> {
private state: IteratorState<T>[] = [];
handle(newState: IteratorState<T>) {
const nextState = this.state.pop();
if(typeof nextState == 'undefined') return this.state.push(newState);
if(isStateHandler(newState) && !isStateHandler(nextState)) return consume(nextState, newState);
if(!isStateHandler(newState) && isStateHandler(nextState)) return consume(newState, nextState);
this.state.unshift(nextState);
this.state.push(newState);
}
next(value?: any): Promise<IteratorResult<T>> {
return new Promise<IteratorResult<T>>((resolve, reject) => {
this.handle([resolve, reject]);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment