【问题标题】:Execute multiple different retrofit calls that depend on a single RxTextView执行依赖于单个 RxTextView 的多个不同的改造调用
【发布时间】:2017-02-11 06:23:51
【问题描述】:

我有一个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;

                }
            })

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

【问题讨论】:

    标签: android rx-java rx-android


    【解决方案1】:

    你很接近。只需将 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(...
    

    【讨论】:

    • 所以我可以订阅四次requestObservable?这对我来说是新的!我会稍后检查它,因为它现在很晚,我会让你知道它是如何运行的(并接受答案!)。谢谢!
    猜你喜欢
    • 2018-04-12
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 2019-02-25
    • 1970-01-01
    • 1970-01-01
    • 2015-02-03
    相关资源
    最近更新 更多