Skip to content

Instantly share code, notes, and snippets.

@Johnz86
Created July 15, 2019 15:45
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Johnz86/b5a7d20c0c98e42c0372ff4318e38efc to your computer and use it in GitHub Desktop.
Save Johnz86/b5a7d20c0c98e42c0372ff4318e38efc to your computer and use it in GitHub Desktop.
RxJS implementation of fromFetch with node-fetch node module
import { Observable } from 'rxjs';
import fetch, { RequestInit, Request, Response } from 'node-fetch';
import AbortController from 'abort-controller';
export type RequestInit = RequestInit;
export function fromFetch(input: string | Request, init?: RequestInit): Observable<Response> {
return new Observable<Response>(subscriber => {
const controller = new AbortController();
const signal = controller.signal;
let outerSignalHandler: () => void;
let abortable = true;
let unsubscribed = false;
if (init) {
// If a signal is provided, just have it teardown. It's a cancellation token, basically.
if (init.signal) {
outerSignalHandler = () => {
if (!signal.aborted) {
controller.abort();
}
};
init.signal.addEventListener('abort', outerSignalHandler);
}
init.signal = signal;
} else {
init = { signal };
}
fetch(input, init).then(response => {
abortable = false;
subscriber.next(response);
subscriber.complete();
}).catch(err => {
abortable = false;
if (!unsubscribed) {
// Only forward the error if it wasn't an abort.
subscriber.error(err);
}
});
return () => {
unsubscribed = true;
if (abortable) {
controller.abort();
}
};
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment