Skip to content

Instantly share code, notes, and snippets.

@leonardokl
Last active January 13, 2020 09:48
Show Gist options
  • Save leonardokl/80a18660ffe65405738dcbc3997fd132 to your computer and use it in GitHub Desktop.
Save leonardokl/80a18660ffe65405738dcbc3997fd132 to your computer and use it in GitHub Desktop.
AbortController implementation with XMLHttpRequest - https://codesandbox.io/s/92vnjok08r
class AbortError extends Error {
name = "AbortError";
message = "Aborted";
}
class AbortSignal extends EventTarget {
aborted = false;
}
class AbortController {
signal = new AbortSignal();
abort = () => {
const event = new CustomEvent("abort");
this.signal.dispatchEvent(event);
this.signal.aborted = true;
};
}
export { AbortError };
export default AbortController;
import { AbortError } from "./AbortController";
const DONE_STATE = 4;
function xhr(url, options = {}) {
return new Promise((resolve, reject) => {
if (options.signal && options.signal.aborted) {
return reject(new AbortError());
}
const method = options.method || "get";
const request = new XMLHttpRequest();
function abort() {
request.abort();
}
request.open(method, url, true);
request.onload = () => {
if (request.status >= 200 && request.status < 400) {
return resolve(JSON.parse(request.responseText));
}
return reject(JSON.parse(request.responseText));
};
if (options.signal) {
options.signal.addEventListener("abort", abort);
xhr.onreadystatechange = function() {
if (xhr.readyState === DONE_STATE) {
options.signal.removeEventListener("abort", abort);
}
};
}
request.onabort = function() {
reject(new AbortError());
};
request.onerror = reject;
request.ontimeout = reject;
request.send(options.body || null);
});
}
export default xhr;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment