执行多个依赖于单个 RxTextView 的不同改造调用

Execute multiple different retrofit calls that depend on a single RxTextView

我有一个 EditText,在它正下方的 ViewPager 中有四个选项卡,我目前正在做的是使用 Retrofit 执行对 Rest 服务的请求文本更改。

 RxTextView.textChangeEvents(searchbar.getEditText())
            .debounce(400, TimeUnit.MILLISECONDS)
            .filter(new Func1<TextViewTextChangeEvent, Boolean>() {
                @Override
                public Boolean call(TextViewTextChangeEvent text) {
                    return (text.text().length() > 2);
                }
            })
            .subscribeOn(AndroidSchedulers.mainThread())
            .observeOn(Schedulers.io())
            .switchMap(new Func1<TextViewTextChangeEvent, Observable<?>>() {
                @Override
                public Observable<?> call(TextViewTextChangeEvent textViewTextChangeEvent) {
                    String searchBarText = textViewTextChangeEvent.text().toString();

                    switch (visibleTab) {
                        case TAGS:
                            return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0));
                        case PEOPLE:
                            return presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0));
                        case COMPANIES:
                            return presenter.executeSearchPostsByCompanies(searchBarText, String.valueOf(0));
                        case JOBS:
                            return presenter.executeSearchPostsByJobs(searchBarText, String.valueOf(0));
                        default:
                            return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0))
                                    .toCompletable().toObservable();
                    }

                }
            })
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<Object>() {
             // here I use EventBus to pass the results to the Fragments (Tabs)
             // ... code omitted ...

您可以从每个选项卡的代码中注意到我有不同的请求。

但现在要求已经改变,对于 EditText 中的每个文本更改,我必须同时执行 所有四个 请求。

我搜索了很多,我发现我可以使用 combineLatest' so I added all four calls tocombineLatest` 但因为它们都依赖于文本更改,所以什么也没发生。

    Observable.combineLatest(presenter.executeSearchPostsByTag( /** what to add as queryText **/ ), 
         presenter.executeSearchPostsByJobs(/** what to add here as queryText**/), //omits the other two calls)

正如您在上方所见,我不知道如何通过 queryText。一定有办法把combineLatest代码和RxTextView.textChangeEvents(searchbar.getEditText())...代码结合起来,直到我一开始发的switchMap但是我没找到。

编辑: 好吧,也许 combineLatest 是错误的,我可以做类似的事情:

                .map(new Func1<String, Boolean>() {
                @Override
                public Boolean call(String s) {

                    presenter.executeSearchPostsByTag(s, String.valueOf(0));
                    presenter.executeSearchPostsByPeople(s, String.valueOf(0));
                    presenter.executeSearchPostsByJobs(s, String.valueOf(0));
                    presenter.executeSearchPostsByCompanies(s, String.valueOf(0));

                    return true;

                }
            })

但我不知道如何将结果发送给订阅者

你很接近。只需将 switchmap 替换为:

.flatMap(new Func1<TextViewTextChangeEvent, Observable<CombinedData>>() {
    @Override
    public Observable<CombinedData> call(TextViewTextChangeEvent textViewTextChangeEvent) {
        String searchBarText = textViewTextChangeEvent.text().toString();

        return Observable.combineLatest(
                presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)), 
                presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0)),
                ...);
        }    
})

为了更好的可读性,创建一个方法来提取组合部分。类似于:

Observable<CombinedData> fetchData(String searchBarText) {
    return Observable.combineLatest(
            presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0)),
            presenter.executeSearchPostsByPeople(searchBarText, String.valueOf(0)),
            ...);
}

不过如果可以的话,还是分成四份比较好。声明一个 Observable:

Observable<TextViewTextChangeEvent> requestObservable = RxTextView.textChangeEvents(searchbar.getEditText())
        .debounce(400, TimeUnit.MILLISECONDS)
        .filter(new Func1<TextViewTextChangeEvent, Boolean>() {
            @Override
            public Boolean call(TextViewTextChangeEvent text) {
                return (text.text().length() > 2);
            }
        })
        .subscribeOn(AndroidSchedulers.mainThread())
        .observeOn(Schedulers.io());

那么您订阅了四次,每次请求:

.flatMap(new Func1<TextViewTextChangeEvent, Observable<Post>>() {
    @Override
    public Observable<Post> call(TextViewTextChangeEvent textViewTextChangeEvent) {
        String searchBarText = textViewTextChangeEvent.text().toString();
        return presenter.executeSearchPostsByTag(searchBarText, String.valueOf(0));
        }
})
.subscribe(...