Rx.Net: Цепочка подписчиков - альтернативный подход? - PullRequest
0 голосов
/ 05 мая 2018

Как мне переписать этот код, чтобы не связывать подписчиков, как показано ниже? Причина для того, чтобы спросить, заключается в том, что этот стиль будет ограничивать наблюдаемое в зависимости от другого наблюдаемого из-за стиля кода, это может привести к путанице.

var results = myService
          .GetData(accountId)    // returns IObservable
          .Subscribe(data =>
          {
              new MyWork().Execute(data)  // returns IObservable
                  .Subscribe(result =>
                  {
                      myResults.Add(result);
                      WriteLine($"Result Id: {result.Id}");
                      WriteLine($"Result Status: {result.Pass}");
                  });
          }); 

Добавлено после первого ответа от Питера Бонса

Ниже приведен код класса MyWork, который имеет метод Execute

public class MyWork 
{
    public virtual IObservable<MyResult> Execute(MyData data)
    {
        MyResult result = null;

        return IsMatch(data)
            .Do(isMatch =>
            {
                if (isMatch)
                {
                    result = new MyResult(1, true);
                }
            })
            .Select(_ => result);
    }


    public IObservable<bool> IsMatch(MyData data)
    {
        return true;
    }
}

1 Ответ

0 голосов
/ 06 мая 2018

Это действительно довольно просто.

var results =
    myService
      .GetData(accountId)
      .SelectMany(data => new MyWork().Execute(data))
      .Subscribe(result =>
      {
          myResults.Add(result);
          Console.WriteLine($"Result Id: {result.Id}");
          Console.WriteLine($"Result Status: {result.Pass}");
      });

Если вы подписываетесь в рамках подписки, значит, вы делаете что-то не так. Запомни. Почти всегда есть способ сделать это простым запросом с одной подпиской.

Просто, чтобы помочь с тестированием, вот код, необходимый, чтобы сделать этот пример Минимальный, Полный и Проверяемый .

public static class myService
{
    public static IObservable<MyData> GetData(int x)
        => Observable.Return(new MyData());
}

public class MyWork 
{
    public virtual IObservable<MyResult> Execute(MyData data)
    {
        MyResult result = null;

        return IsMatch(data)
            .Do(isMatch =>
            {
                if (isMatch)
                {
                    result = new MyResult() { Id = 1, Pass = true};
                }
            })
            .Select(_ => result);
    }


    public IObservable<bool> IsMatch(MyData data)
    {
        return Observable.Return(true);
    }
}

public class MyResult
{
    public int Id;
    public bool Pass;
}

public class MyData { }
...