What is it?
ReactiveCommand is a Reactive Extensions and asynchronous aware implementation of the ICommand interface and can be executed either synchronously or asynchronously.
What is it for?
It turns a method into an observable. Hence, we can bind it to any event, can observe it, get its result and do anything further.
Creating
Executing
There are many ways to execute a method, we can directly execute it or turn it into a command. Furthermore, the command also has many ways to let us execute it.
Hence, we need to know what we expect from the method:
- If it is just a method in view model, view doesn’t care about it, we just directly execute it.
- If the view need to observe it:
- For fire and forget: use “1” from Executing part
- For a command that needs checking use “2” from Executing part
- There is a sequence of commands like: A -> B -> C -> D and View only care about A and D we need to call B inside A by using “3” from Executing part
Sample code of implementation for a set of commands that need to be run in order: A -> B -> C -> D:
Performance in order from fastest to slowest:
- Directly call
- Await Execute()
- Execute().Subcribe()
- Invoke
Side Effects:
Actually, the binding is not real real-time like we think it is.
Just check out the following code:
command 2 and command 3 are supposed to be called after command 1 finished.
But, the result is not what we expected:
Command 2 was not called, why?
- As we can see, command 2 and command 3 only can be executed when command 1 is finished.
- When command 1 is finished, its IsExecuting changed to False to enable command 2 and command 3. But, at that time, this IsExecuting was not bound to CanExecute, so it won’t let us execute command2.
- For command3, we got the Delay, after a short time (likes 100ms), everything was bound and had the expected value, so the command3 can be executed.
So, to avoid it, we have 3 options:
- Use delay (which is the worst).
- Use directly IsExecuting from the command without any binding.
- Call the needed command inside the executing command. (Recommended)