ahooks
Version:
react hooks library
60 lines (59 loc) • 2.46 kB
JavaScript
import throttle from 'lodash/throttle';
import { useEffect, useRef } from 'react';
import { cancelPendingPromise } from '../utils/cancelledError';
const useThrottlePlugin = (fetchInstance, { throttleWait, throttleLeading, throttleTrailing }) => {
const throttledRef = useRef(undefined);
const pendingRejectRef = useRef(undefined);
const options = {};
if (throttleLeading !== undefined) {
options.leading = throttleLeading;
}
if (throttleTrailing !== undefined) {
options.trailing = throttleTrailing;
}
useEffect(() => {
if (throttleWait) {
const _originRunAsync = fetchInstance.runAsync.bind(fetchInstance);
throttledRef.current = throttle((callback) => {
callback();
}, throttleWait, options);
// throttle runAsync should be promise
// https://github.com/lodash/lodash/issues/4400#issuecomment-834800398
fetchInstance.runAsync = (...args) => {
cancelPendingPromise(pendingRejectRef);
return new Promise((resolve, reject) => {
var _a;
let callbackInvoked = false;
pendingRejectRef.current = reject;
(_a = throttledRef.current) === null || _a === void 0 ? void 0 : _a.call(throttledRef, () => {
callbackInvoked = true;
pendingRejectRef.current = undefined;
_originRunAsync(...args)
.then(resolve)
.catch(reject);
});
if (!callbackInvoked && options.trailing === false) {
cancelPendingPromise(pendingRejectRef);
}
});
};
return () => {
var _a;
fetchInstance.runAsync = _originRunAsync;
(_a = throttledRef.current) === null || _a === void 0 ? void 0 : _a.cancel();
cancelPendingPromise(pendingRejectRef);
};
}
}, [throttleWait, throttleLeading, throttleTrailing]);
if (!throttleWait) {
return {};
}
return {
onCancel: () => {
var _a;
(_a = throttledRef.current) === null || _a === void 0 ? void 0 : _a.cancel();
cancelPendingPromise(pendingRejectRef);
},
};
};
export default useThrottlePlugin;