Skip to content

Commit

Permalink
Use AbortController when available
Browse files Browse the repository at this point in the history
  • Loading branch information
tchak committed May 22, 2019
1 parent 5760a4b commit 7dea021
Showing 1 changed file with 53 additions and 52 deletions.
105 changes: 53 additions & 52 deletions packages/@orbit/jsonapi/src/jsonapi-request-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,22 +22,12 @@ import JSONAPIURLBuilder, { JSONAPIURLBuilderSettings } from './jsonapi-url-buil
import { JSONAPISerializer, JSONAPISerializerSettings } from './jsonapi-serializer';
const { assert, deprecate } = Orbit;

export interface FetchSettings {
headers?: object;
method?: string;
export interface FetchSettings extends RequestInit {
json?: object;
body?: string;
params?: any;
timeout?: number;
credentials?: string;
cache?: string;
redirect?: string;
referrer?: string;
referrerPolicy?: string;
integrity?: string;
}


export interface JSONAPIRequestProcessorSettings {
sourceName: string;
SerializerClass?: (new (settings: JSONAPISerializerSettings) => JSONAPISerializer);
Expand Down Expand Up @@ -82,52 +72,33 @@ export default class JSONAPIRequestProcessor {
}

fetch(url: string, customSettings?: FetchSettings): Promise<any> {
let settings = this.initFetchSettings(customSettings);

let fullUrl = url;
if (settings.params) {
fullUrl = this.urlBuilder.appendQueryParams(fullUrl, settings.params);
delete settings.params;
}

let fetchFn = (Orbit as any).fetch || Orbit.globals.fetch;

// console.log('fetch', fullUrl, settings, 'polyfill', fetchFn.polyfill);

if (settings.timeout) {
let timeout = settings.timeout;
delete settings.timeout;
const settings = this.initFetchSettings(customSettings);
const urlWithQueryParams = this.urlBuilder.appendQueryParams(url, settings);
const AbortController = (Orbit as any).AbortController || Orbit.globals.AbortController;
const timeout = settings.timeout;
delete settings.timeout;
let promise;

if (timeout && !AbortController) {
promise = polyfillFetchWithTimeout(urlWithQueryParams, settings, timeout);
} else {
const fetch = (Orbit as any).fetch || Orbit.globals.fetch;

return new Promise((resolve, reject) => {
let timedOut: boolean;
if (timeout && AbortController) {
const controller = new AbortController();
settings.signal = controller.signal;

let timer = Orbit.globals.setTimeout(() => {
timedOut = true;
reject(new NetworkError(`No fetch response within ${timeout}ms.`));
Orbit.globals.setTimeout(() => {
controller.abort();
}, timeout);
}

fetchFn(fullUrl, settings)
.catch((e: Error) => {
Orbit.globals.clearTimeout(timer);

if (!timedOut) {
return this.handleFetchError(e);
}
})
.then((response: any) => {
Orbit.globals.clearTimeout(timer);

if (!timedOut) {
return this.handleFetchResponse(response);
}
})
.then(resolve, reject);
});
} else {
return fetchFn(fullUrl, settings)
.catch((e: Error) => this.handleFetchError(e))
.then((response: any) => this.handleFetchResponse(response));
promise = fetch(urlWithQueryParams, settings);
}

return promise
.catch((e: Error) => this.handleFetchError(e))
.then((response: Response) => this.handleFetchResponse(response));
}

initFetchSettings(customSettings: FetchSettings = {}): FetchSettings {
Expand Down Expand Up @@ -249,3 +220,33 @@ export default class JSONAPIRequestProcessor {
throw new NetworkError(e);
}
}

function polyfillFetchWithTimeout(url: string, settings: FetchSettings, timeout: number) {
const fetch = (Orbit as any).fetch || Orbit.globals.fetch;

return new Promise((resolve, reject) => {
let timedOut: boolean;

let timer = Orbit.globals.setTimeout(() => {
timedOut = true;
reject(new NetworkError(`No fetch response within ${timeout}ms.`));
}, timeout);

fetch(url, settings)
.catch((e: Error) => {
Orbit.globals.clearTimeout(timer);

if (!timedOut) {
throw e;
}
})
.then((response: Response) => {
Orbit.globals.clearTimeout(timer);

if (!timedOut) {
return response;
}
})
.then(resolve, reject);
});
}

0 comments on commit 7dea021

Please sign in to comment.