2017-01-01 3 views
4

У меня есть коллекция объектов, назовите их obj. У них есть метод act(). Метод act() в конечном итоге вызовет event(), наблюдаемый на o, для вызова onComplete.Chain Observables

Что такое хороший способ их соединения?

То есть, вызов o.act(), ждать o.event().onComplete и затем вызвать следующую o2.act(), и так далее в течение неопределенного количества o в коллекции.

Так что подпись так:

public class Item { 
    final protected PublishSubject<Object> event = PublishSubject.create(); 

    public Observable<ReturnType> event() { 
     return event; 
    } 

    public void act() { 
     // do a bunch of stuff 
     event.onComplete(); 
    } 
} 

А потом в потребляющей код:

Collection<Item> items... 
foreach item in items 
    item.act -> await item.event().onComplete() -> call next item.act() -> so on 
+0

Вам нужно вернуть o.act() в o2.act()? Если нет, можете ли вы запустить все это асинхронно? – Sebas

+0

@Sebas o2, o3 и т. Д. Каждый может зависеть от побочных эффектов предыдущего выполнения (но не фактического значения возврата) – mtyson

+0

Итак, вопрос заказа, правильно? – Sebas

ответ

2

Если я правильно понимаю, ваши объекты имеют такую ​​подпись:

public class Item { 
    public Observable<ReturnType> event()... 
    public ReturnType act()... 
} 

Итак, если они были заполнены так:

public class Item { 

    private final String data; 
    private final Observable<ReturnType> event; 

    public Item(String data) { 
     this.data = data; 

     event = Observable 
       .fromCallable(this::act); 
    } 

    public Observable<ReturnType> event() { 
     return event; 
    } 

    public ReturnType act() { 
     System.out.println("Item.act: " + data); 
     return new ReturnType(); 
    } 
} 

Они могли бы быть соединены таким образом:

Item item1 = new Item("a"); 
Item item2 = new Item("b"); 
Item item3 = new Item("c"); 

item1.event() 
     .concatWith(item2.event()) 
     .concatWith(item3.event()) 
     .subscribe(); 

Результат:

Item.act: a 
Item.act: b 
Item.act: c 

Тогда, если у вас есть Iterable коллекции, вы можете использовать flatMap:

Iterable<Item> items = Arrays.asList(item1, item2, item3); 

Observable.from(items) 
     .flatMap(Item::event) 
     .subscribe(); 

Alternative

Альтернативой, что больше похоже на ваш случай может быть:

public class Item { 
    private final PublishSubject<Void> event = PublishSubject.create(); 

    private final String data; 

    public Item(String data) { 
     this.data = data; 
    } 

    public Observable<Void> event() { 
     return event; 
    } 

    public Void act() { 
     System.out.println("Item.act: " + data); 
     // do a bunch of stuff 
     event.onCompleted(); 
     return null; 
    } 
} 

использование:

Iterable<Item> iterable = Arrays.asList(item2, item3); 

item1.event(). 
     concatWith(Observable.from(iterable) 
       .map(Item::act)) 
     .subscribe(); 

item1.act(); 

Но не использует event() на пункты 2 и далее.

+0

Это действительно близко, извините за скудные детали. Я обновил вопрос, используя класс Item. спасибо – mtyson

+0

Значит, вы хотите отбить все это, вызвав первый «акт»? – weston

+0

Это правда, да! – mtyson