IME, race conditions are quite rare and pretty easy to solve in JS, because the flow of code execution is only susceptible to be interrupted at known locations (async function calls). Here's an example of how you could solve the problem you mentioned in a few lines of JavaScript:
function createRunExclusive() {
let runningTask = Promise.resolve();
return async (asyncFn) => {
runningTask = runningTask.then(async () => {
return await asyncFn();
});
return runningTask;
}
}
// Example usage:
// The idea is that any command that should not overlap should use the same "runExclusive" function
const runExclusive = createRunExclusive();
function handleIpTablesCommand() {
runExclusive(async () => {
await doSomethingWithIpTables();
})
}
Although it's probably best to just use one of the queue libraries on npm. This one for example: https://www.npmjs.com/package/p-queue