jscommand
Command pattern for JavaScript
Create a command
To create a command, create a class that inherits from Command.
class Add extends Command
{
constructor(private a:number)
{
super();
}
action(data:any): any
{
return data + this.a;
}
}
let command = new Add(3);
await command.execute(2);
Conditional command
A command can be executed conditionally by using IfCommand.
await new IfCommand(false, new Add(2)).execute(1);
await new IfCommand(true, new Add(2)).execute(1);
Chain commands
Commands can be chained and executed in as a single unit by using MacroCommand.
let commands = new MacroCommand();
commands.add(new Add(3));
commands.add(new Add(4));
commands.add(new Add(5));
await commands.execute(0);
Rollback commands
A command can be rolled back if it inherits from RevertableCommand.
class Add extends RevertableCommand
{
constructor(private a:number)
{
super();
}
action(data:any): any
{
if(data > 2) throw new Error('Overflow!')
return data + this.a;
}
revert(data:any): any
{
console.log('Rollback')
}
}
let commands = new RevertableMacroCommand();
commands.add(new Add(1));
commands.add(new Add(1));
commands.add(new Add(1));
commands.add(new Add(1));
await commands.execute(0);
Logging command
A command execution can be logged by wrapping the command with TraceableCommand
new TraceableCommand(new Add(3)).execute(1);
Fail-safe command
To supporess an error from a command, wrap the command with FailSafeCommand
new FailSafeCommmand(new CouldThrowAnErrorCommand()).execute();
Retryable command
A command can be retried if an expected error occurs if the command is wrapped with RetryableCommand.
new RetryableCommand(new Add(3), Error, 3).execute(0);
Sleep command
A sleep command sets a ranom timeout between to millisecond valuesCommands can be chained to perform complex operations.
let minMsWait = 50;
let maxMsWait = 1500;
new SleepCommand(minMsWait, maxMsWait).execute(0);
Function-based command
For simplicity, AnonymousCommand can be used to wrap a function so that a function can act as a command.
let command = new AnonymousCommand((a)=>a+1);
await command.execute(2);
Nested commands
Commands can be chained to perform complex operations.
let commands = new MacroCommand();
commands.add(new IfCommand(new AnonymousCommand((a)=>a+1 > 2), new Add(1));
commands.add(new RetryableCommand(new Add(2)));
new TraceableCommand(commands).execute(0);
One-of commands
A OneOf command executes the given commands in order and will return once
a command executed successfully. The remaining commands will not be executed.
let commands = new OneOfCommand();
commands.add(new DoSomeThingCommand());
commands.add(new TryThisIfTheFirstCommandFailed()));
commands.add(new TryThisIfTheSecondCommandFailed()));
new TraceableCommand(commands).execute();