UNPKG

@onestone/singleflight

Version:

Ensure only one execution is in-flight for a given key at a time

57 lines (56 loc) 2.13 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Singleflight = void 0; class Singleflight { doing = new Map(); /** * Executes and returns the results of the given function, making sure that * only one execution is in-flight for a given key at a time. * If a duplicate comes in, the duplicate caller waits for the original * to complete and receives the same results. * @param key The unique identifier for this function execution * @param fn The function to be executed * @returns A promise that resolves with the result of the function execution * @throws Any error that occurs during the function execution */ async do(key, fn) { const existing = this.doing.get(key); if (existing) { return existing; } const promise = fn(); this.doing.set(key, promise); let result; try { result = await promise; } finally { this.doing.delete(key); } return result; } /** * Generates a unique key for a function call based on the function name and its arguments. * @param fn The function to generate a key for * @param args The arguments passed to the function * @returns A string representation of the function call */ static makeKey(fn, ...args) { return `${fn.name}(${args.map((arg) => JSON.stringify(arg)).join(",")})`; } /** * Executes a function and ensures only one execution is in-flight at a time, for a given * combination of function name and argument values. * @param fn The function to be executed * @param args The arguments to be passed to the function * @returns A promise that resolves with the result of the function execution * @throws Any error that occurs during the function execution */ async doAuto(fn, ...args) { const key = Singleflight.makeKey(fn, ...args); return await this.do(key, async () => { return await fn(...args); }); } } exports.Singleflight = Singleflight;