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 Jul 5, 2019
1 parent 1a058b6 commit 7df1936
Showing 1 changed file with 53 additions and 51 deletions.
104 changes: 53 additions & 51 deletions packages/@orbit/jsonapi/src/jsonapi-request-processor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,10 @@ import {
} 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 {
Expand Down Expand Up @@ -90,52 +81,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 @@ -290,3 +262,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 7df1936

Please sign in to comment.