代码之家  ›  专栏  ›  技术社区  ›  SuperJMN

使用reactiveui按顺序执行一组命令

  •  2
  • SuperJMN  · 技术社区  · 6 年前

    我有一个 ViewModel 带着一些 ReactiveCommands 该用户可以手动调用。

    CommandA
    CommandB
    CommandC
    

    所以用户只能调用 ,或 一个 先,然后 C类 是的。

    问题是 我想创建另一个命令来运行它们 ,从A到C。它们不应该并行运行,但是 按顺序 是的。

    如何才能对给定的特征进行命令?

    3 回复  |  直到 6 年前
        1
  •  1
  •   Luis    6 年前

    导入system.reactive.linq,现在您可以:

    {
        await CommandA.Execute();
        await CommandB.Execute();
        await CommandC.Execute();
    }
    

    system.reactive.linq使iobservable成为可等待的。

        2
  •  3
  •   Taylor Buchanan    6 年前

    既然你想让他们按顺序执行, ReactiveCommand.CreateCombined 不是很合适。但是,您可以创建类似于 CombinedReactiveCommand 为你的情况工作。

    可以通过调用 ReactiveCommand<TParam,TResult>.Execute ,它返回 IObservable<TResult> 返回单个值的。因此,一个非常基本的实现可以将它与 SelectMany 以下内容:

    ReactiveCommand.CreateFromObservable(() =>
        CommandA.Execute()
            .SelectMany(_ => CommandB.Execute())
            .SelectMany(_ => CommandC.Execute()));
    

    如果所有命令都具有相同的类型,则可以使其更通用:

    var commands = new[] { CommandA, CommandB, CommandC };
    ReactiveCommand.CreateFromObservable(() =>
        commands.Aggregate(
            Observable.Return(Unit.Default),
            (acc, cur) => acc.SelectMany(_ => cur.Execute())));
    

    但是,这并没有考虑到combinedreactivecommand句柄的其他内容,例如 CanExecute ThrownExceptions 是的。如果需要处理这些问题,那么可以考虑滚动自己的combinedReactiveCommand。

        3
  •  0
  •   Adrián Romero    6 年前

    我想你的命令是 ReactiveCommand<Unit,Unit> 所以,你可以这样做:

    public class MyCoolViewModel
    {
       bool runSequentially = false;
    
       public ReactiveCommand<Unit, Unit> Command { get; set; }
       public ReactiveCommand<Unit, Unit> Command2 { get; set; }
       public ReactiveCommand<Unit, Unit> Command3 { get; set; }
       public ReactiveCommand<Unit, Unit> CommandwhoInvokesOtherCommands { get; set; }
    
    
       public MyCoolViewModel()
       {
    
           Command = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
           {    
            runSequentially= false;
            Console.WriteLine("Start 1");
            await Task.Delay(1000);
            Console.WriteLine("End 1");
            return Unit.Default;
           });
          Command2 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
          {
            runSequentially = false;
            Console.WriteLine("Start 2");
            await Task.Delay(1000);
            Console.WriteLine("End 2");
            return Unit.Default;
          });
    
        Command3 = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
        {
            Console.WriteLine("Start 3");
            await Task.Delay(1000);
            Console.WriteLine("End 3");
            return Unit.Default;
        });
    
        CommandwhoInvokesOtherCommands = ReactiveCommand.CreateFromTask<Unit, Unit>(async _ =>
          {
              Console.WriteLine("Invoking other commands");
              runSequentially = true;
              await Task.Delay(1000);
              Console.WriteLine("End");
              return Unit.Default;
          });
    
                /*Command 1, 2 and 3 only will run if flag is set to true*/
        CommandwhoInvokesOtherCommands.Where(_ => runSequentially).InvokeCommand(Command);
        Command.Where(_ => runSequentially).InvokeCommand(Command2);
        Command2.Where(_ => runSequentially).InvokeCommand(Command3);
    
        //Observable.Return(Unit.Default).InvokeCommand(CommandwhoInvokesOtherCommands);//for test purposes
    
    }
    }
    

    当一个命令返回时,实用程序方法invokecommand将调用另一个命令,因此这个方法加上where子句将完成这项任务。

    我希望这对你有帮助 当做