async-wrappers
Version:
A set of wrapper functions to perform debouncing, throttling, retrying etc.
117 lines (99 loc) • 2.7 kB
JavaScript
/**
* @internal
*/
import pending from './pending';
import { latestArguments } from './callReducers';
/**
* @internal
*/
/**
* @internal
*/
var wrap = (fn, before, after) => {
var wrapped = fn;
if (before && after) {
wrapped = function wrapped() {
before();
var result = fn(...arguments);
after();
return result;
};
} else if (before) {
wrapped = function wrapped() {
before();
var result = fn(...arguments);
return result;
};
} else if (after) {
wrapped = function wrapped() {
var result = fn(...arguments);
after();
return result;
};
}
return wrapped;
};
/**
* @internal
*/
var getRunner = (fn, args, result) => () => {
try {
result.complete(fn(...args));
} catch (e) {
result.error(e);
}
};
/**
* @internal
*/
// eslint-disable-next-line @typescript-eslint/no-empty-function
var empty = () => {};
/**
* @internal
*
* Utility function that wraps a function and will use a reducer to combine the arguments
* of multiple calls to that function. As the function is not executed until it is invoked
* a promise for the result is returned to the callers.
*
* @param fn The function to wrap.
* @param {?argumentsReducer} callReducer Used to determine the arguments when `fn` is invoked.
* This will be called every time the wrapped function is called.
* If not supplied the default implementation of only using the latest arguments will be used.
* @param onBeforeReduce If supplied this function will be called before the reducer is called.
* @param onAfterReduce If supplied this function will be called if the wrapped function is cancelled.
* @returns
*/
var callReduce = (fn, callReducer, onBeforeReduce, onAfterReduce) => {
var reducer = typeof callReducer === 'function' ? callReducer : latestArguments;
var result = null;
var args = [];
var reject = reason => {
if (result !== null) {
result.error(reason ? reason : new Error('reset'));
result = null;
args = [];
}
}; // capture the invocation state
var prepare = () => {
if (result === null) {
// sanity check no result pending
return empty;
}
var run = getRunner(fn, args, result);
result = null;
args = [];
return run;
};
var call = wrap(function () {
for (var _len = arguments.length, callArgs = new Array(_len), _key = 0; _key < _len; _key++) {
callArgs[_key] = arguments[_key];
}
args = reducer(args, callArgs);
if (result === null) {
result = pending();
}
return result.promise;
}, onBeforeReduce, onAfterReduce);
return [call, prepare, reject];
};
export default callReduce;