You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
Sven Slootweg 5ad97cd53e Initial version 3 months ago
.gitignore Initial version 3 months ago
README.md Initial version 3 months ago
example.js Initial version 3 months ago
index.js Initial version 3 months ago
package.json Initial version 3 months ago
pnpm-lock.yaml Initial version 3 months ago

README.md

single-concurrent

Small utility function to ensure that you're not running two copies of an asynchronous procedure at once.

Particularly useful for cases where you have some sort of processing loop that gets kicked off by a specific event, but that should only do so if it isn't already running.

Works with any function that returns a Promise (so this includes async functions).

Example

"use strict";

const singleConcurrent = require("single-concurrent");

(async function () {
	let trySomeAsyncProcess = singleConcurrent(async function someAsyncProcess() {
		// Let's pretend that this is some long-running task that internally recurses
		console.log("started some async process");
		await new Promise((resolve) => {
			setTimeout(resolve, Math.random() * 2000);
		});
		console.log("finished some async process");
	});

	trySomeAsyncProcess();
	trySomeAsyncProcess(); // oops! it was already running and we tried to run it again
})();

/* Output (note how it's only output once):

started some async process
finished some async process
*/

API

singleConcurrent(callback)

  • callback: The function that does the actual work, and that should only be run one at a time. This must return a Promise! A function marked async also meets that requirement by default.

Returns: A wrapper function that will only execute the callback if one is not already in progress; it passes through the arguments and return value (assuming the underlying callback is actually run, of course).

If the returned wrapper function is called while the procedure is still running, the call is simply ignored and synchronously returns with undefined. Once the underlying async procedure finishes, a call to the wrapper function will activate the underlying callback again, so it can be reused - it just prevents multiple runs from occurring simultaneously.