使用Observable Zip行为不端

时间:2016-10-10 15:20:49

标签: android rx-java retrofit2

我有两个可观察对象(A,B),我希望第一个在第二次运行之前完成运行。但是,这甚至不是我所遇到的问题。问题是,当在B之前添加A时,B根本不会运行,除非我在A之前放置B然后,两个运行。但是,我所处的场景就像这样:

  • A - 皮卡
  • B - 交付

订单有三种类型。 Pickup OnlyDelivery OnlyPickup And DeliveryPickups需要在Deliveries之前运行。 Delivery只有Pickup标记为true。仅Pickup,关闭时需picked up and delivered。这就是为什么我需要Pickup在发送货物之前先发送所有本地保存的皮卡。所以,我这样做了:

拾取

private Observable<UpdateMainResponse> getDeliveredOrders() {

    String token = PrefUtil.getToken(context);

    BehaviorSubject<Integer> pageControl = BehaviorSubject.create(1);
    Observable<UpdateMainResponse> ret = pageControl.asObservable().concatMap(integer -> {

        if (integer - 1 != deliveryUpdate.size()) {
            Log.e(TAG, "DeliveredOrders: " + deliveryUpdate.size());
            RealmOrderUpdate theDel = deliveryUpdate.get(integer-1);
            Log.e(TAG, "DeliveryUpdate: " + theDel.toString());
            DeliverOrder pickupOrder = new DeliverOrder();
            pickupOrder.setUuid(theDel.getUuid());
            pickupOrder.setCode(theDel.getDest_code());
            pickupOrder.setDelivered_lat(theDel.getLoc_lat());
            pickupOrder.setDelivered_long(theDel.getLoc_long());
            return apiService.deliverOrder(theDel.getOrderId(), token, pickupOrder)
                    .subscribeOn(Schedulers.immediate())
                    .doOnNext(updateMainResponse -> {
                        try {
                            Log.e(TAG, updateMainResponse.toString());
                            realm.executeTransaction(realm1 -> theDel.deleteFromRealm());
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            pageControl.onNext(integer + 1);
                        }
                    });
        } else {
            return Observable.<UpdateMainResponse>empty().doOnCompleted(pageControl::onCompleted);
        }
    });

    return Observable.defer(() -> ret);
}

投放

private Observable<UpdateMainResponse> getPickedOrders() {

    Log.e(TAG, "PickedOrders: " + pickUpdate.size());

    String token = PrefUtil.getToken(context);

    BehaviorSubject<Integer> pageControl = BehaviorSubject.create(1);
    Observable<UpdateMainResponse> ret = pageControl.asObservable().concatMap(integer -> {

        Log.e(TAG, "MainPickedInteger: " + integer);
        if (integer - 1 != pickUpdate.size()) {
            RealmOrderUpdate thePick = pickUpdate.get(integer - 1);
            Log.e(TAG, "PickedUpdate: " + thePick.toString());
            PickupOrder pickupOrder = new PickupOrder();
            pickupOrder.setUuid(thePick.getUuid());
            pickupOrder.setCode(thePick.getSource_code());
            pickupOrder.setPicked_lat(thePick.getLoc_lat());
            pickupOrder.setPicked_long(thePick.getLoc_long());
            return apiService.pickupOrder(thePick.getOrderId(), token, pickupOrder)
                    .subscribeOn(Schedulers.immediate())
                    .doOnNext(updateMainResponse -> {
                        try {
                            Log.e(TAG, updateMainResponse.toString());
                            realm.executeTransaction(realm1 -> thePick.deleteFromRealm());
                        } catch (Exception e) {
                            e.printStackTrace();
                        } finally {
                            pageControl.onNext(integer + 1);
                        }
                    });
        } else {
            return Observable.<UpdateMainResponse>empty().doOnCompleted(pageControl::onCompleted);
        }
    });

    return Observable.defer(() -> ret);
}

拉链

private Observable<ZipperResponse> batchedZip() {
    return Observable.zip(getPickedOrders(), getDeliveredOrders(), (updateMainResponse, updateMainResponse2) -> {
        List<UpdateMainResponse> orders = new ArrayList<>();
        bakeries.add(updateMainResponse);
        bakeries.add(updateMainResponse2);
        return new ZipperResponse(orders);
    });
}

使用Zipper

public void generalUpload(APIRequestListener listener) {

    batchedZip.subscribe(new Subscriber<ZipperResponse>() {
        @Override
        public void onCompleted() {
            listener.didComplete();
            unsubscribe();
        }

        @Override
        public void onError(Throwable e) {
            listener.handleDefaultError(e);
            unsubscribe();
        }

        @Override
        public void onNext(ZipperResponse zipperResponse) {
            Log.e(TAG, zipperResponse.size());
        }
    });
}

问题

  1. 我不知道为什么getDeliveredOrders()没有被调用,除非我把它移到getPickedOrders()之前的第一个

  2. 阅读Rx Documentation for Zip我可以看到它无法按照我的预期在getPickedOrders()运行之前所有getDeliveredOrders()首先运行的情况下工作。它必须逐个完成。例如:提货之一,然后是交货之一

  3. 任何帮助理解正在发生的事情都将受到赞赏。感谢

1 个答案:

答案 0 :(得分:1)

好的,如果我做对了:

  • 仅限提货:需要完成提货流程,然后才能完成。
  • 仅交付:需要完成交付流程,然后才能完成。
  • 提货和交货:需要先通过提货,然后通过交货。

在很高的层面上,几乎是preudo-code,为什么这个过程不起作用?

Observable<Item> performPickup(Item item);
Observable<Item> performDelivery(Item item);
Observable<Items> items = ...;

items
.flatMap(item -> item.needsPickup() ? performPickup(item) : Observable.just(item))
.flatMap(item -> item.needsDelivery() ? performDelivery(item) : Observable.just(item))
.doOnNext(completedItem -> ...)

如果您有三种类型的不同来源:

Observable<Item> items = Observable.merge(
     pickupSource(),
     deliverySource(),
     pickupAndDeliverySource());