A simple utility to ensure that concurrent calls with the same key share the same Promise, preventing duplicate executions.
- 🌀 Prevents duplicate async calls for the same key
- 🪝 TypeScript support
- 🛠️ Simple API, easy integration
npm install --save promise-singleflight
const PromiseSingleflight = require("promise-singleflight");
const singleflight = PromiseSingleflight.create();
function delay(ms) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function queryData(path) {
return singleflight(path, async () => {
console.log(`start queryData ${path}`);
await delay(1000);
console.log(`end queryData ${path}`);
return `data:${path}`;
});
}
(async function () {
const items = await Promise.all([
queryData('/a'),
queryData('/a'),
queryData('/b'),
]);
console.log(items.join('\n'));
})();
Output:
start queryData /a
start queryData /b
end queryData /a
end queryData /b
data:/a
data:/a
data:/b
Creates a singleflight wrapper function.
key
: Any value that can be used as a Map key (string, number, etc.)fn
: An async function returning a Promise
Returns: A Promise that resolves to the result of fn
. If multiple calls are made with the same key before the first resolves, they will all share the same Promise.
import { create } from "promise-singleflight";
const singleflight = create<string, number>();
async function fetchNumber(key: string): Promise<number> {
return singleflight(key, async () => {
// ...fetch or compute
return 42;
});
}
- Prevents redundant network/database calls
- Reduces server load and improves efficiency
- Ensures data consistency for concurrent requests
- TypeScript 4.5: New File Extensions
- Example TypeScript Package
- ts-jest
- ts-node
- eslint-config-standard-with-typescript
MIT