All files / hof reuseInFlight.js

87.5% Statements 14/16
100% Branches 9/9
80% Functions 4/5
87.5% Lines 14/16

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 421x 12x                   3x         3x   3x 12x 1x 1x     12x 12x   6x     6x 6x               12x    
const DEFAULT_CONFIG = {
	createKey(args) { return JSON.stringify(args); },
	ignoreSingleUndefined: false
};
 
// for a given Promise-generating function, track each execution by the stringified
// arguments. if the function is called again with the same arguments, then instead
// of generating a new promise, an existing in-flight promise is used instead. This
// prevents unnecessary repetition of async function calls while the same function
// is still in flight.
export default function reuseInFlight(asyncFn, config) {
	config = {
		...DEFAULT_CONFIG,
		...(config || {})
	};
 
	const inflight = {};
 
	return function debounced(...args) {
		if (config.ignoreSingleUndefined && args.length === 1 && args[0] === undefined) {
			console.warn('Ignoring single undefined arg (reuseInFlight)');
			args = [];
		}
 
		const key = config.createKey(args);
		if (!Object.prototype.hasOwnProperty.call(inflight,key)) {
			// WE DO NOT AWAIT, we are storing the promise itself
			inflight[key] = asyncFn.apply(this, args)
				.then(results => {
					// self invalidate
					delete inflight[key];
					return results;
				}, err => {
					// still self-invalidate, then rethrow
					delete inflight[key];
					throw err;
				});
		}
 
		return inflight[key];
	};
}