![](/img/trans.png)
[英]Do an action before any subscriber callback of an Observable is called in 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.