![](/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.