Use fetch and AbortController instead of XHR

This commit is contained in:
Eduard Urbach 2019-04-26 16:57:22 +09:00
parent 361cce4b39
commit 511f830a32
2 changed files with 26 additions and 27 deletions

View File

@ -34,6 +34,9 @@ const fetchOptions: RequestInit = {
credentials: "same-origin" credentials: "same-origin"
} }
// Error message
const searchErrorMessage = "Looks like the website is offline, please retry later."
// Speech recognition // Speech recognition
let recognition: SpeechRecognition let recognition: SpeechRecognition
@ -119,7 +122,7 @@ export async function search(arn: AnimeNotifier, search: HTMLInputElement, evt?:
// Start searching anime // Start searching anime
fetch("/_/anime-search/" + term, fetchOptions) fetch("/_/anime-search/" + term, fetchOptions)
.then(showResponseInElement(arn, url, "anime", results["anime"])) .then(showResponseInElement(arn, url, "anime", results["anime"]))
.catch(console.error) .catch(_ => arn.statusMessage.showError(searchErrorMessage))
requestIdleCallback(() => { requestIdleCallback(() => {
// Check that the term hasn't changed in the meantime // 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) fetch(`/_/${key}-search/` + term, fetchOptions)
.then(showResponseInElement(arn, url, key, results[key])) .then(showResponseInElement(arn, url, key, results[key]))
.catch(console.error) .catch(_ => arn.statusMessage.showError(searchErrorMessage))
} }
}) })
} catch(err) { } 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) { function showResponseInElement(arn: AnimeNotifier, url: string, typeName: string, element: HTMLElement) {
return async (response: Response) => { return async (response: Response) => {
if(!response.ok) {
throw response.statusText
}
let html = await response.text() let html = await response.text()
if(html.includes("no-search-results")) { if(html.includes("no-search-results")) {

View File

@ -13,7 +13,7 @@ export default class Application {
loading: HTMLElement loading: HTMLElement
currentPath: string currentPath: string
originalPath: string originalPath: string
lastRequest: XMLHttpRequest | null lastRequestController: AbortController | null
contentInvisible: boolean contentInvisible: boolean
onError: (err: Error) => void onError: (err: Error) => void
@ -36,35 +36,27 @@ export default class Application {
this.ajaxify(links) this.ajaxify(links)
} }
get(url: string): Promise<string> { async get(url: string): Promise<string> {
// return fetch(url, { if(this.lastRequestController) {
// credentials: "same-origin" this.lastRequestController.abort()
// }).then(response => response.text())
if(this.lastRequest) {
this.lastRequest.abort()
this.lastRequest = null
} }
return new Promise((resolve, reject) => { this.lastRequestController = new AbortController()
let request = new XMLHttpRequest()
request.timeout = 20000 try {
request.onerror = () => reject(new Error("You are either offline or the requested page doesn't exist.")) const response = await fetch(url, {
request.ontimeout = () => reject(new Error("The page took too much time to respond.")) credentials: "same-origin",
request.onload = () => { signal: this.lastRequestController.signal
if(request.status < 200 || request.status >= 400)
reject(request.responseText)
else
resolve(request.responseText)
}
request.onabort = () => console.warn("Request canceled:", request)
request.open("GET", url, true)
request.send()
this.lastRequest = request
}) })
if(!response.ok) {
throw response.statusText
}
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) { load(url: string, options?: LoadOptions) {