【问题标题】:RxJava: code with the conditionRxJava:带有条件的代码
【发布时间】:2016-09-23 09:18:51
【问题描述】:

我搜索城市,如果它不存在,我想采取与城市存在时不同的行动。

public void onAddButtonClick(String cityName) {
        Subscription subscription = repository.getCity(cityName)
                .filter(city -> city != null)
                .subscribeOn(backgroundThread)
                .flatMap(city -> repository.saveCityToDb(city))
                .observeOn(mainThread)
                .subscribe(city -> view.cityExists());

        subscriptions.add(subscription);
}

getCity()方法:

public Observable<City> getCity(String name){
        return fileRepository.getCityFromFile(name);
    }

getCityFromFile()

public Observable<City> getCityFromFile(String cityName){
        try {
            InputStream is = assetManager.open(FILE_NAME);
            Scanner scanner = new Scanner(is);
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();
                if (line.toLowerCase().contains(cityName.toLowerCase())) {
                    String[] cityParams = line.split("\t");
                    City city = new City();
                    city.setId(Long.parseLong(cityParams[0]));
                    city.setName(cityParams[1]);
                    return Observable.fromCallable(() -> city);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        return Observable.fromCallable(() -> null);
    }

因此,当找不到城市时,我想向用户发出警报,当找到城市时,我想走得更远(将其保存到数据库,打开主屏幕等)。我使用运算符 filter(),但这并不是我想要的,如果 city == null 就不会更进一步。 你能建议一些更好的主意吗?

【问题讨论】:

    标签: java android rx-java rx-android


    【解决方案1】:

    这取决于您如何设计代码。

    如果您搜索一个城市但没有找到,可能会返回一个Observable.empty。或返回 Observable.error (如果是错误情况)。然后,您可以使用另一个Observable 以防空/错误Observable

    例如:

        Observable<City> observableIfNoCity = /** observable with perform actions when where is no city */
        repository.getCity(wrongCity) // return an Observable.empty if no city
                  .flatMap(city -> repository.saveCityToDb(city))
                  .doOnNext(city -> view.cityExists())
                  .switchIfEmpty(observableIfNoCity)
                  .subscribe();
    

    如果您返回 Observable.error,您可以使用 onErrorResumeNext 而不是 switchIfEmpty

    但要正确行事,我认为您应该避免在getCityFromFile 中发出null 值。请改用emptyerror

     public Observable<City> getCityFromFile(String cityName){
          return Observable.defer(() -> {
             try {
                InputStream is = assetManager.open(FILE_NAME);
                Scanner scanner = new Scanner(is);
                while (scanner.hasNextLine()) {
                    String line = scanner.nextLine();
                    if (line.toLowerCase().contains(cityName.toLowerCase())) {
                        String[] cityParams = line.split("\t");
                        City city = new City();
                        city.setId(Long.parseLong(cityParams[0]));
                        city.setName(cityParams[1]);
                        return Observable.just(city);
                    }
                }
            } catch (IOException e) {
                 return Observable.error(e);
            }
    
            return Observable.empty(); // or Observable.error(new NotFoundException());
        });
    }
    

    【讨论】:

    • 如果找到城市,我什么时候放 view.cityExists() 方法?它会是另一个 Observable 以相同的方法吗?
    • 所以,结果我不明白如何使用 switchIfEmpty() (我会更详细地阅读它),但我喜欢返回 Observable.error(e); 的想法。或 Observable.empty(); ,所以在 onAddButtonClick() 中我在 subscribe() 方法中添加了以下代码:throwable -&gt; view.showCouldNotFindCity(), () -&gt; view.showCouldNotFindCity()
    【解决方案2】:

    您可以使用Observable.error() 抛出一个错误并在SubsriberonError() 方法中捕获它。:

    Subscription subscription = Observable.just("String")
                .flatMap(city -> city == null ? Observable.error(new NullPointerException("City is null")) : Observable.just(city))
                .subscribeOn(backgroundThread)
                .flatMap(city -> repository.saveCityToDb(city))
                .observeOn(mainThread)
                .subscribe(city -> view.cityExists(),
                        throwable -> view.showError());
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 2011-05-30
      • 2016-08-31
      • 2016-05-01
      • 2018-12-20
      相关资源
      最近更新 更多