Skip to content

Instantly share code, notes, and snippets.

@scorsi
Last active February 27, 2020 15:06
Show Gist options
  • Save scorsi/77b7c77d0aec5b0e215e653e7ef6c6fd to your computer and use it in GitHub Desktop.
Save scorsi/77b7c77d0aec5b0e215e653e7ef6c6fd to your computer and use it in GitHub Desktop.
Automaticaly cancel Promise when component did unmount compatible with AbortController for fetch
import { useEffect, useRef } from 'react';
export function PromiseCanceledError() {
this.name = 'PromiseCanceledError';
}
const makeCancelable = (promise, abortController) => {
let isCanceled = false;
const wrappedPromise = new Promise((resolve, reject) => {
promise
.then((val) => (isCanceled ? reject(new PromiseCanceledError()) : resolve(val)))
.catch((error) => (isCanceled ? reject(new PromiseCanceledError()) : reject(error)));
});
return {
promise: wrappedPromise,
cancel() {
isCanceled = true;
if (abortController !== null) abortController.abort();
},
};
};
export default () => {
const promises = useRef([]);
useEffect(() => () => {
promises.current.forEach((p) => p.cancel());
promises.current = [];
}, []);
const cancellablePromise = (p, abortController = null) => {
const cPromise = makeCancelable(p, abortController);
promises.current.push(cPromise);
return cPromise.promise;
};
return {
cancellablePromise,
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment