Skip to content

Instantly share code, notes, and snippets.

@WimJongeneel
Last active February 20, 2022 18:46
Show Gist options
  • Save WimJongeneel/cb31f38651a4ab9d69ecca36b0f9a3c9 to your computer and use it in GitHub Desktop.
Save WimJongeneel/cb31f38651a4ab9d69ecca36b0f9a3c9 to your computer and use it in GitHub Desktop.
UseQueuedPromise: a React hook that runs a promise and uses a one-sized queue to ensure only one promise is running at the same time. Scheduling a new promise will overwrite any scheduled promises and the final result will always be the result of the last promise that was sent to the hook.
interface UsePromise<a> {
run: () => void
result: a
error: Error
status: 'pending' | 'rejected' | 'resolved' | 'iddle'
}
const useQueuedPromise = <a,>(promise: () => Promise<a>): UsePromise<a> => {
const [ result, setResult ] = React.useState<a>()
const [ error, setError ] = React.useState<Error>()
const [ status, setStatus ] = React.useState<UsePromise<a>['status']>('iddle')
const [ next, setNext ] = React.useState<() => Promise<a>>()
const run = React.useCallback(() => {
setNext(() => promise)
}, [promise])
React.useEffect(() => {
if(next == null) return
if(status == 'pending') return
setStatus('pending')
setError(null)
setResult(null)
setNext(null)
next()
.then(r => {
setResult(r)
setStatus('resolved')
})
.catch(e => {
setError(e)
setStatus('rejected')
})
}, [next, status])
return { run, result, error, status }
}
const usePromise = <a,>(promise: () => Promise<a>): UsePromise<a> => {
const [ result, setResult ] = React.useState<a>()
const [ error, setError ] = React.useState<Error>()
const [ status, setStatus ] = React.useState<UsePromise<a>['status']>('pending')
const run = React.useCallback(() => {
setStatus('pending')
setError(null)
setResult(null)
promise()
.then(r => {
setResult(r)
setStatus('resolved')
})
.catch(e => {
setError(e)
setStatus('rejected')
})
}, [promise])
return { run, result, error, status }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment