如何追踪Reactive Command执行完成并挂载后续执行方法?
嘿,这个问题我太熟悉了!Reactive Command本身就设计了丰富的生命周期Observable,完全不用在命令的处理方法里硬塞后续逻辑——刚好匹配你的场景。下面分两部分给你讲清楚:
Reactive Command自带了几个原生的Observable来帮你追踪执行状态,最常用的有两种:
利用
ExecutionCompletedObservable
这是最直接的方式,每次命令执行完成(无论成功还是失败)都会触发这个Observable,还能拿到执行结果的详细信息。代码示例:// 假设你的命令是MyReactiveCommand MyReactiveCommand.ExecutionCompleted.Subscribe(result => { if (result.IsSuccess) { Console.WriteLine("命令执行成功!"); // 还能拿到执行结果:result.Result } else { Console.WriteLine($"命令执行失败,错误:{result.Exception.Message}"); } });监听
IsExecuting的状态变化
如果你只关心「执行结束」这个事件,不关心结果,可以监听IsExecuting这个IObservable<bool>——当它从true切换到false时,就代表执行完成了:MyReactiveCommand.IsExecuting .DistinctUntilChanged() // 过滤重复的状态,避免多次触发 .Where(isExecuting => !isExecuting) // 只关注从执行中变为未执行的时刻 .Subscribe(_ => { Console.WriteLine("命令执行结束了(不管成功失败)"); });
既然不能在命令处理方法里直接调用,我们可以通过Observable的操作符来实现「自动串联」,完全解耦原命令和后续逻辑:
如果后续逻辑是另一个Reactive Command
用InvokeCommand操作符直接把两个命令绑定起来,还能按需过滤触发条件(比如只在原命令成功时触发):MyReactiveCommand.ExecutionCompleted .Where(result => result.IsSuccess) // 可选:只在成功时触发后续命令 .Select(_ => Unit.Default) // 传递后续命令需要的参数,无参数就传Unit.Default .InvokeCommand(MyFollowUpReactiveCommand);这样原命令每次执行完成(符合条件的话),就会自动触发后续命令,完全不需要修改原命令的处理逻辑。
如果后续是普通方法
直接在ExecutionCompleted的订阅里调用即可,注意如果是UI操作,要切换到主线程:MyReactiveCommand.ExecutionCompleted .ObserveOn(RxApp.MainThreadScheduler) // UI场景下必须切换到主线程 .Subscribe(result => { if (result.IsSuccess) // 按需判断是否执行后续 { MyFollowUpMethod(); // 调用你的后续方法 } });单次执行时串联逻辑
如果你只是想在某一次调用命令后触发后续方法,可以直接对Execute()返回的Observable进行串联:MyReactiveCommand.Execute(CommandParameter) .Then(_ => MyFollowUpMethod()) // 命令执行完成后调用方法 .Catch(ex => { // 处理错误,避免订阅终止 Console.WriteLine($"执行出错:{ex.Message}"); return Observable.Empty<Unit>(); }) .Subscribe();
小提醒
- 注意线程调度:Reactive Command默认在后台线程执行,如果你后续方法涉及UI操作,一定要用
ObserveOn(RxApp.MainThreadScheduler)切换线程。 - 错误处理:如果原命令执行失败,你可以选择触发或不触发后续逻辑,通过
Where(result => result.IsSuccess)来控制。
内容的提问来源于stack exchange,提问作者Anton Zhmyrov

