改造链接可观察量

时间:2015-03-28 16:55:48

标签: android asynchronous retrofit observable rx-java

我正在尝试使用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");
});

}

1 个答案:

答案 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) });

forEachsubscribe非常相似,只是它明确阻止。您甚至可以将它与原始代码一起使用,但添加一个空的onNext操作将不会非常干净。

如果您还可以提供有关您的应用程序结构的更多详细信息(这是一个主要方法吗?它是一个Android应用程序吗?等等)我可以提供更多关于尽可能避免阻止的指示。