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

对不包含所有项的集合引发错误

  •  0
  • ekjcfn3902039  · 技术社区  · 5 年前

    我想知道用RxJava语法遍历一个集合并在不存在任何项时引发错误的最干净的方法是什么。下面显示了一个混合示例,但理想情况下,我希望所有逻辑都使用RxJava语法

    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);
    }
    
    0 回复  |  直到 5 年前
        1
  •  2
  •   César Chrétien    5 年前

    实际上,如果您在下游传播一个错误(如果找不到id)并在需要处理该错误的地方订阅,就可以实现这一点。还可以很容易地包含有关丢失的栏的信息,例如:

    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语句,则将执行subscribe方法的第二个lambda,并显示抛出的错误。

    我从使用rx中学到的:当你开始对它感到更舒服的时候,它开始感觉像一个漂亮的新锤子,突然间一切都像一个钉子。记住,只有当它让你的生活更容易,而不是更难的时候才使用它。

        2
  •  1
  •   ctranxuan    5 年前

    也许你也可以有这样的东西:

    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流中的错误?