簡體   English   中英

在返回訂閱服務器之前,如何攔截可觀察對象並在RxJava中修改它?

[英]How can I intercept an observable object and modify it in RxJava before returning to Subscriber?

我正在嘗試命中一個服務並返回一個對象列表,在它返回給訂閱者之前,我想對列表中的每個對象進行另一個同步調用,以進行另一個服務調用來設置一個丟失的字段。 我已成功完成所有調用,但訂閱者返回的對象具有此字段,我需要將其設置為null。 這是我的代碼示例:

示例服務:

rx.Observable<List<ExampleObject>> getExampleObject();
rx.Observable<MissingObject> getMissingObjectByFoo(@Path("foo") String foo);

示例類:

public class ExampleObject {
    String foo;
    MissingObject bar;

    public String getFoo() {
        return this.foo;
    }

    public void setFoo(String value) {
        this.foo = value;
    }

    public MissingObject getBar() {
        return this.bar;
    }

    public void setBar(MissingObject value) {
        this.bar = value;
    }
}

示例實施:

mService.getExampleObject().flatMap(new Func1<List<ExampleObject>, Observable<?>>() {
            @Override
            public Observable<List<ExampleObject>> call(List<ExampleObject> exampleObjects) {
                for (ExampleObject entry : exampleObjects) {
                    String foo = entry.getFoo();
                    mService.getMissingObjectByFoo(foo)
                            .subscribeOn(mScheduler.backgroundThread())
                            .observeOn(mScheduler.mainThread())
                            .subscribe(new Subscriber<MissingObject>() {
                        @Override
                        public void onCompleted() {

                        }

                        @Override
                        public void onError(Throwable e) {

                        }

                        @Override
                        public void onNext(MissingObject missingObject) {
                            entry.setBar(missingObject);
                        }
                    });
                }
                return Observable.just(exampleObjects);
            };

因為您更新條目的中間調用是異步的,所以我認為您不能堅持使用List<ExampleObject> ,而應該直接從Observable操作ExampleObject

mService.getExampleObject()
    // Spread the list
    .flatMap(list -> Observable.from(list))
    // Update your object
    // Here we zip the object with the missing object,
    // so that when the missing object is obtained,
    // we update the entry and emit it.
    .flatMap(entry -> Observable.zip(
           Observable.just(entry), 
           mDocsService.getMissingObjectByFoo(entry.getFoo()), 
           (entry, missingObject) -> {
               entry.setBar(missingObject);
               return entry;
           })
    )
    // if you really want a map after all
    .toList();

邊注:

如果您在map中的功能取決於外部變量(條目),那么您可以跳過該zip。 這是我試圖避免的,但無論如何它在這里:

    .flatMap(entry -> mDocsService.getMissingObjectByFoo(entry.getFoo())
                                  .map(missingObject -> {
                                      entry.setBar(missingObject);
                                      return entry;
                                   })
    )

您正在尋找zip運算符,如下所述: Zip運算符 我想你想把你的所有電話的拉鏈平面映射到一個拉鏈,所以,像這樣:

    mService.getExampleObject().flatMap(new Func1<List<ExampleObject>, Observable<ExampleObject>>() {
        @Override
        public Observable<List<ExampleObject>> call(List<ExampleObject> exampleObjects) {
            List<Observable<ExampleObject>> allTheObservables = new ArrayList<Observable<ExampleObject>>();
            for (ExampleObject entry : exampleObjects) {
                allTheObservables.add(mService.getMissingObjectByFoo(foo).map(new Func1<MissingObject, ExampleObject>() {
                    @Override
                    public ExampleObject call(MissingObject missingObject) {
                        return entry.setBar(missingObject);
                    }
                }));
            }
            return Observable.zip(allTheObservables, new FuncN<ExampleObject>() {
                @Override
                public ExampleObject call(ExampleObject... args) {
                    return Arrays.asList(args);
                }
            });
        }
    });

如果不起作用,或者存在語法問題,這是一個具體的例子,使用github api:

    service.getContributorsObservable("square", "dagger")
        .flatMap(new Func1<List<Contributor>, Observable<List<String>>>() {
            @Override
            public Observable<List<String>> call(List<Contributor> contributors) {
                List<Observable<String>> allTheObservables = new ArrayList<>(contributors.size());
                for (final Contributor contributor : contributors) {
                    allTheObservables.add(service.getContributorsObservable(contributor.login).map(new Func1<User, String>() {

                        @Override
                        public String call(User user) {
                            return contributor.login + " is " + user.name;
                        }
                    }));
                }
                return Observable.zip(allTheObservables, new FuncN<List<String>>() {
                    @Override
                    public List<String> call(Object... args) {
                        return Arrays.asList((String[]) args);
                    }
                });
            }
        });

請記住,這將進行n + 1個網絡調用,1表示ExampleObject列表,然后是該列表中的每個ExampleObject 1個。 如果可能我強烈建議你使用API的維護者,以獲得在API方面的信息查找照顧說話。 只知道這將使用一些帶寬!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM