Блокировка выполнения метода до тех пор, пока не вернется асинхронный вызов RxJava - PullRequest
0 голосов
/ 06 ноября 2018

Я почти уверен, что кто-то задал этот вопрос раньше, но я не могу его найти. Я пытаюсь сделать что-то довольно простое даже для начинающего RxJava, как я. У меня есть следующий метод:

 public ILocation findLocationDetails() {
    requestLocationDetails();
    return buildLocationFromDetails();
}

Метод requestLocationDetails содержит вызов REST, который выполняется внутри другого потока:

private void requestLocationDetails() {
    compositeDisposable.add(
        Observable
        .fromCallable((() -> JsonRestCaller.readJsonFromUrl(buildUrl())))
        .subscribeOn(Schedulers.io())
        .subscribeWith(new DisposableObserver<JsonObject>() {
            @Override
            public void onNext(JsonObject jsonObject) {
                try {
                    parseJson(jsonObject);
                } catch (IOException e) {
                    Log.e(TAG, e.getMessage());
                }
            }
            @Override
            public void onError(Throwable e) {
                Log.e(TAG, e.getMessage());
            }
            @Override
            public void onComplete() {
            }
    }));
}

Теперь все, что я хочу сделать, это дождаться завершения parseJson (), чтобы метод buildLocationFromDetails мог работать с деталями, полученными в parseJson.

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

1 Ответ

0 голосов
/ 07 ноября 2018

Вы можете попробовать что-то вроде ниже

//Create a method which will parse json and return the result in String 
//(I am assuming string as parse response for simplicity)
public Observable<String> parseJson(JsonObject jsonObject) {
    return Observable
        .create(
            e -> {
                //parse json code goes here.
                // Once parsing done pass the details
                e.onNext("Details from parsing json");
                e.onComplete();
            }
        );
}

Теперь измените код, который вы написали выше,

Observable
    .fromCallable((() -> JsonRestCaller.readJsonFromUrl(buildUrl())))
    //Pass the jsonObject from above to parseJson() method
    .flatMap(jsonObject -> parseJson(jsonObject))
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    //details is the string from parsing json
    .subscribe(
        details -> buildLocationFromDetails(details),
        error -> new Throwable(error)
    );

Надеюсь, это поможет.

...