From 511f830a32ae560ce3a0e700cf6d24070495bad6 Mon Sep 17 00:00:00 2001 From: Eduard Urbach Date: Fri, 26 Apr 2019 16:57:22 +0900 Subject: [PATCH] Use fetch and AbortController instead of XHR --- scripts/Actions/Search.ts | 11 ++++++++-- scripts/Application.ts | 42 ++++++++++++++++----------------------- 2 files changed, 26 insertions(+), 27 deletions(-) diff --git a/scripts/Actions/Search.ts b/scripts/Actions/Search.ts index 2c416068..00adc3f3 100644 --- a/scripts/Actions/Search.ts +++ b/scripts/Actions/Search.ts @@ -34,6 +34,9 @@ const fetchOptions: RequestInit = { credentials: "same-origin" } +// Error message +const searchErrorMessage = "Looks like the website is offline, please retry later." + // Speech recognition let recognition: SpeechRecognition @@ -119,7 +122,7 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: // Start searching anime fetch("/_/anime-search/" + term, fetchOptions) .then(showResponseInElement(arn, url, "anime", results["anime"])) - .catch(console.error) + .catch(_ => arn.statusMessage.showError(searchErrorMessage)) requestIdleCallback(() => { // Check that the term hasn't changed in the meantime @@ -135,7 +138,7 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: fetch(`/_/${key}-search/` + term, fetchOptions) .then(showResponseInElement(arn, url, key, results[key])) - .catch(console.error) + .catch(_ => arn.statusMessage.showError(searchErrorMessage)) } }) } catch(err) { @@ -147,6 +150,10 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?: function showResponseInElement(arn: AnimeNotifier, url: string, typeName: string, element: HTMLElement) { return async (response: Response) => { + if(!response.ok) { + throw response.statusText + } + let html = await response.text() if(html.includes("no-search-results")) { diff --git a/scripts/Application.ts b/scripts/Application.ts index b9160b55..8b96016f 100644 --- a/scripts/Application.ts +++ b/scripts/Application.ts @@ -13,7 +13,7 @@ export default class Application { loading: HTMLElement currentPath: string originalPath: string - lastRequest: XMLHttpRequest | null + lastRequestController: AbortController | null contentInvisible: boolean onError: (err: Error) => void @@ -36,35 +36,27 @@ export default class Application { this.ajaxify(links) } - get(url: string): Promise { - // return fetch(url, { - // credentials: "same-origin" - // }).then(response => response.text()) - - if(this.lastRequest) { - this.lastRequest.abort() - this.lastRequest = null + async get(url: string): Promise { + if(this.lastRequestController) { + this.lastRequestController.abort() } - return new Promise((resolve, reject) => { - let request = new XMLHttpRequest() + this.lastRequestController = new AbortController() - request.timeout = 20000 - request.onerror = () => reject(new Error("You are either offline or the requested page doesn't exist.")) - request.ontimeout = () => reject(new Error("The page took too much time to respond.")) - request.onload = () => { - if(request.status < 200 || request.status >= 400) - reject(request.responseText) - else - resolve(request.responseText) + try { + const response = await fetch(url, { + credentials: "same-origin", + signal: this.lastRequestController.signal + }) + + if(!response.ok) { + throw response.statusText } - request.onabort = () => console.warn("Request canceled:", request) - request.open("GET", url, true) - request.send() - - this.lastRequest = request - }) + return await response.text() + } catch(err) { + throw "Seems like there was an error accessing this page...retrying after 3 seconds." + } } load(url: string, options?: LoadOptions) {