async-wrappers
Version:
A set of wrapper functions to perform debouncing, throttling, retrying etc.
90 lines (73 loc) • 2.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _callReduce = _interopRequireDefault(require("./callReduce"));
var _deferred = _interopRequireDefault(require("./deferred"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
/**
* Ensure multiple calls to a function will only execute at most once every
* `delay` milliseconds.
*
* The execution will always happens asynchronously. If the delay is `0` then
* execution will occur after the current runtime event loop.
*
* The throttled function returns a promise that resolves to the return value
* of `func`.
*
* By default the arguments to `func` are the latest arguments given to the
* throttled function. For custom behaviour pass an `argumentsReducer`
* function.
*
* @param func The function to throttle
* @param delay The number of milliseconds between executions.
* @param options Debounce options
* @return The throttled function
*
* @category Wrapper
*/
const throttle = (func, delay = 50, options = {}) => {
const {
reducer,
onCancel,
maxCalls
} = options;
let calls = 0;
const afterReduce = () => {
if (maxCalls) {
calls++;
if (calls >= maxCalls) {
flush();
return;
}
} // nothing pending so go
if (execute.delay < 0) {
const elapsed = execute.called > 0 ? Date.now() - execute.called : delay; // call right away or with how much time to go before next call
execute.defer(elapsed >= delay ? 0 : delay - elapsed);
}
};
const [call, runner, reject] = (0, _callReduce.default)(func, reducer, undefined, afterReduce);
const execute = (0, _deferred.default)(() => {
calls = 0;
runner()();
});
const flush = () => {
calls = 0;
execute.cancel();
(0, _deferred.default)(runner()).defer(0);
};
const cancel = reason => {
execute.cancel();
if (onCancel) {
onCancel();
}
reject(reason ? reason : new Error('cancelled'));
};
const wrapped = call;
wrapped.cancel = cancel;
wrapped.flush = flush;
return wrapped;
};
var _default = throttle;
exports.default = _default;