【发布时间】:2017-09-16 02:36:37
【问题描述】:
我有一个需要输入并返回输出的服务:
Item callService(Item input);
输入始终是可观察对象发出的前一个元素,服务调用的输出应该是可观察对象发出的下一个元素。并且应该重复这个序列,直到一个项目满足某个条件。
实际上,我有一片树叶,我将树叶发送到一个服务,该服务告诉我它的父级是什么。我会继续这样做,直到找到根。
我的第一个解决方案:
我递归调用一个 flatMap 函数。由于递归,我不喜欢这个解决方案:
Observable.just(Item.of("start"))
.map(Result::of)
.flatMap(App::fallbackUntilIsRoot)
.blockingSingle();
private static Observable<Result> fallbackUntilIsRoot(Result previousResult)
{
if (previousResult.isRoot())
{
return Observable.just(previousResult);
} else
{
return Service.call(previousResult.getItem())
.flatMap(App::fallbackUntilIsRoot); // recursion
}
}
我的第二个解决方案:
我维护一个外部队列,基本上我用这个队列提供 observable。看起来还是不太好。
Queue<Item> todoList = new LinkedList<>(Collections.singleton(Item.of("start")));
Result result = Observable.range(1, Integer.MAX_VALUE) //max tries
.concatMap(attempt -> Service.call(todoList))
.takeUntil(Result::isEmpty)
.takeLast(2)
.firstElement()
.blockingGet();
public class Service
{
private static final Queue<Item> itemsProvidedByService = new LinkedList<>(
Arrays.asList(Item.of("first"), Item.of("second"), Item.of("third"), Item.of("fourth"), Item.of("root")));
public static Observable<Result> call(Queue<Item> todoList)
{
Item previousItem = todoList.poll();
Item newItem = itemsProvidedByService.poll(); // we could pass previousItem to a real service here
if (newItem == null)
{
return Observable.just(Result.empty());
}
todoList.add(newItem);
return Observable.just(Result.of(newItem));
}
}
有没有一种 Rx 方式来进行这种链接?
【问题讨论】: