Last active
February 27, 2020 15:06
-
-
Save scorsi/77b7c77d0aec5b0e215e653e7ef6c6fd to your computer and use it in GitHub Desktop.
Automaticaly cancel Promise when component did unmount compatible with AbortController for fetch
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
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