Вызовите ошибку на коллекции, которая не содержит все элементы - PullRequest
0 голосов
/ 31 октября 2019

Мне интересно, как лучше всего пройтись по коллекции в синтаксисе RxJava и вызвать ошибку, если какой-либо элемент не существует. Гибридный пример показан ниже, но в идеале я хотел бы, чтобы вся логика в синтаксисе RxJava была ::1001*

public Single<List<Bar>> doSomething(Collection<String> ids) {
  Single<List<Bar>> bars = getAllBars();
  List<Bar> results = bars
  .flattenAsObservable(z-> z)
  .filter(bar -> ids.contains(bar.getId())
  .toList()
  .blockingGet();// Blocking since I don't know the RxJava syntax for below

  if (results.isEmpty()) {
    throw SomeError();
  }
  if (results.size() != ids.size()) {
    // Ideally know which bar(s) are not in the ids list
    throw someError();
  }
  return Single.just(results);
}

Ответы [ 2 ]

2 голосов
/ 01 ноября 2019

На самом деле, это может быть достигнуто довольно просто, если вы распространяете ошибку в нисходящем направлении, если идентификатор не найден, и подписываетесь, где бы вы ни хотели воздействовать на эту ошибку. Также довольно легко включить информацию об отсутствующих столбцах, например, так:

public Single<List<Bar>> doSomething(Collection<String> ids) {
  return getAllBars()
    .map(bars -> {
      List<Bar> unknownBars = new ArrayList<>();
      for(Bar bar : bars) {
        if(!ids.contains(bar.getId()) {
          unknownBars.add(bar);
        }
      }
      if (unknownBars.isEmpty()) {
        return bars;
      } else {
        throw new BarsNotFoundException(unknownBars);
      }
    });
}

//elsewhere
doSomething(ids)
  .subscribe(bars -> { /* do something */ }, throwable -> { /* handle error */ });

Если оператор throw достигнут на вашей карте, вторая лямбда вашего метода подписки будет выполнена с ошибкой, которую выЯ бросил.

То, что я узнал, используя сам rx: Когда вы начинаете чувствовать себя более комфортно с ним, он начинает ощущаться как новый модный молоток, и вдруг все выглядит как гвоздь. Не забывайте использовать его только тогда, когда оно облегчает вашу жизнь, а не усложняет ее.

1 голос
/ 01 ноября 2019

Может быть, у вас может быть что-то подобное:

public static void main(String[] args) {
    Collection<String> ids = List.of("id4", "id2", "id1", "id3"); // same ids
    // Collection<String> ids = List.of("id4", "id2", "id1", "id5"); // different ids
    // Collection<String> ids = List.of("id4", "id2", "id1", "id3", "id5"); // different ids
    // Collection<String> ids = List.of("id4", "id2", "id1"); // different ids

    doSomething(ids)
            .subscribe(l -> System.out.println("received: " + toString((List<Bar>) l)),
                       err -> System.err.println(err.getMessage()));

    Flowable.timer(60, SECONDS) // Just to block the main thread for a while
            .blockingSubscribe();
}

private static Single<List<Bar>> doSomething(Collection<String> ids) {
    return getAllBars().flatMap(bars -> {
                           List<String> unknownBarIds = bars.stream().map(Bar::getId).collect(Collectors.toList());
                           unknownBarIds.removeAll(ids);
                           return unknownBarIds.isEmpty()
                                            ? Single.just(bars)
                                            : Single.error(new Exception("unknown bars: " + unknownBarIds));
                       })
                       .flatMap(bars -> {
                           List<String> barIds = bars.stream().map(Bar::getId).collect(Collectors.toList());
                           List<String> missingIds = new ArrayList<>(ids);
                           missingIds.removeAll(barIds);
                           return missingIds.isEmpty()
                                        ? Single.just(bars)
                                        : Single.error(new Exception("missing bars: " + missingIds));
                       });
}

private static Single<List<Bar>> getAllBars() {
    return Single.just(List.of(new Bar("id2"), new Bar("id1"), new Bar("id3"), new Bar("id4")));
}

private static String toString(final List<Bar> bars) {
    return bars.stream().map(Bar::getId).collect(Collectors.joining(", "));
}

, если вы хотите сохранить ошибку в потоке rx?

...