Last active
August 24, 2019 15:47
-
-
Save sergey-shpak/a9db25efb9b64a036c112f4a3ebc3689 to your computer and use it in GitHub Desktop.
Abortable fetch (js fetch abort / cancel fetch / stop request )
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
As you may know fetch requests can be aborted only with AbortController | |
https://developer.mozilla.org/ru/docs/Web/API/AbortController | |
The 'request helper' is exposing abort method into promise, | |
allowing aborting from outside of the promise, for example: | |
``` | |
import { request } from 'helpers' | |
request('https://some/path') | |
.then(response => response.json()) | |
.catch(e => console.log(e)) | |
.abort() // to immediately abort request | |
``` | |
`request` signature is the same as for `fetch` method | |
https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch | |
Enjoy! | |
*/ | |
// ES5 Old School with with some ES6 features | |
export const request = (source, init) => { | |
const controller = Reflect.construct(AbortController,[]) | |
const { signal } = controller | |
function PromiseController(){ | |
return Reflect.construct(Promise, arguments, PromiseController) | |
} | |
Object.defineProperty(PromiseController, Symbol.species, { | |
get: () => PromiseController | |
}) | |
PromiseController.prototype = Object.create(Promise.prototype, { | |
constructor: { value: PromiseController }, | |
abort: { value: () => controller.abort() } | |
}) | |
return PromiseController((res, rej) => { | |
fetch(source, { signal, ...init }).then(res, rej) | |
}) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// ES6 | |
export const request = (source, init) => { | |
const controller = new AbortController() | |
const { signal } = controller | |
class PromiseController extends Promise { | |
static get [Symbol.species](){ | |
return PromiseController | |
} | |
abort(){ | |
controller.abort() | |
} | |
} | |
return new PromiseController((res, rej) => { | |
fetch(source, { signal, ...init }).then(res, rej) | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment