繁体   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