Skip to content

Instantly share code, notes, and snippets.

@MarekZeman91
Last active April 25, 2022 15:27
Show Gist options
  • Save MarekZeman91/c222af1eba8d5a0ded8efee7ec0b54ec to your computer and use it in GitHub Desktop.
Save MarekZeman91/c222af1eba8d5a0ded8efee7ec0b54ec to your computer and use it in GitHub Desktop.
import { CancelTokenSource } from 'axios';
import { useCallback, useRef } from 'react';
import { newCancelTokenSource } from '../network/api/Network';
import { delay } from '../utils/FlowUtils';
import { useOnComponentUnmount } from './useOnComponentUnmount';
import { useScope } from './useScope';
// when your callback returns usePoolingCallback.RETRY, it retries after delay
export const usePoolingCallback = <R, D>(
callback: (cancelTokenSource: CancelTokenSource, data: D) => Promise<R | typeof usePoolingCallback.RETRY>,
poolingDelay = 250
) => {
const cancelTokenSource = useRef<CancelTokenSource>();
const scope = useScope({ callback, poolingDelay });
useOnComponentUnmount(() => cancelTokenSource.current?.cancel());
return useCallback(
async (data?: D) => {
cancelTokenSource.current?.cancel();
cancelTokenSource.current = newCancelTokenSource();
const currentCancelTokenSource = cancelTokenSource.current;
let result = await scope.callback(currentCancelTokenSource, data as unknown as D);
while (result === usePoolingCallback.RETRY) {
await delay(scope.poolingDelay, currentCancelTokenSource.token);
result = await scope.callback(currentCancelTokenSource, data as unknown as D);
}
return result;
},
[scope]
);
};
usePoolingCallback.RETRY = Symbol('RETRY');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment