我正在尝试使用rxjava进行改造。我有一个问题,即彼此链接改装的可观测量或者由我创建的可观察物。一些例子:
Observable<List<Friend>> friendsListObservable = friendsService.getFriends();
Observable<Void> updateReqestObservable = friendsListObservable.switchMap(friends -> {
Log.d(TAG, "Hello");
return userAPI.updateFriends(session.getUserId(), friends);
}).subscribe();
一切都被调用,直到它到达switchMap。所以hello永远不会显示,但是如果我返回例如Observable.just(null)
而不是改装observable它可以正常工作。此外,如果我在没有链接的情况下使用改装的observable,它就可以工作。
EDIT1:
这是一个Android应用程序。似乎根本没有调用map运算符。有时也会发生改造可观察的情况。我仍然认为它与线程有关。根据我的理解,在发出项目时调用运算符,但调用onNext
不会触发map
运算符。以下是我的全部代码:
public Observable<List<FacebookFriend>> getFriends() {
PublishSubject<List<FacebookFriend>> friendsPublishSubject = PublishSubject.create();
Observable<List<FacebookFriend>> returnObservable = friendsPublishSubject.doOnSubscribe(() -> {
Log.d(TAG, "OnSubscribe called");
Session session = Session.getActiveSession();
if (session != null && session.isOpened()) {
new Request(session, "/me/friends", null, HttpMethod.GET,
new Request.Callback() {
public void onCompleted(Response response) {
JSONObject graphResponse = response.getGraphObject()
.getInnerJSONObject();
try {
JSONArray friends = graphResponse.getJSONArray("data");
Gson gson = new Gson();
Type listType = new TypeToken<ArrayList<FacebookFriend>>() {
}.getType();
List<FacebookFriend> friendsList = gson.fromJson(friends.toString(), listType);
friendsPublishSubject.onNext(friendsList);
friendsPublishSubject.onCompleted();
} catch (JSONException e) {
e.printStackTrace();
friendsPublishSubject.onError(e);
}
}
}).executeAsync();
} else {
InvalidSessionException exception = new InvalidSessionException("Your facebook session expired");
friendsPublishSubject.onError(exception);
}
});
return returnObservable.subscribeOn(AndroidSchedulers.mainThread()).observeOn(AndroidSchedulers.mainThread());
}
public Observable<Void> updateFriendsList() {
Observable<List<FacebookFriend>> facebookFriendsListObservable = facebookService.getFriends();
Observable<Void> updateReqestObservable = facebookFriendsListObservable.map(friends -> {
Log.d(TAG, "This is never called");
});
}
答案 0 :(得分:1)
在实际调用点可以绕过阻塞的一种方法是将它订阅到主题,然后在代码的任何部分结束时阻止主题需要执行请求。
例如:
final ReplaySubject<Void> subject = ReplaySubject.create();
friendsService.getFriends()
.switchMap(friends -> userApi.updateFriends(session.getUserId(), friends))
.subscribeOn(Schedulers.io())
.subscribe(subject);
// Do other things that don't require this to be done yet...
// Wherever you need to wait for the request to happen:
subject.toBlocking().singleOrDefault(null);
由于主题也是Observable
,您甚至可以从方法中返回主题,并在以后阻止它。
所有这一切,在那里使用更新调用作为副作用似乎有点奇怪。 updateFriends
也是改造服务吗?如果是这样,您可能需要考虑将更新调用作为同步服务,返回void
而不是您将在onNext调用中调用的Observable<Void>
。如果仍然需要阻止,您可以使用forEach
,如下所示:
friendsService.getFriends()
.forEach(friends -> { userApi.updateFriends(session.getUserId(), friends) });
forEach
与subscribe
非常相似,只是它明确阻止。您甚至可以将它与原始代码一起使用,但添加一个空的onNext
操作将不会非常干净。
如果您还可以提供有关您的应用程序结构的更多详细信息(这是一个主要方法吗?它是一个Android应用程序吗?等等)我可以提供更多关于尽可能避免阻止的指示。