我一直在将RxJava和反应式编程应用于命令行应用程序。我发现了一些非常棒的设计模式,它们确实简化了命令行界面的代码。
但是,我正在努力解决一件事。经常我发光值向下运营商的链,和我concatMap()
的Observable.create()
对发射值征求用户输入。
这很容易,直到我想提供一种方法可以返回到先前的版本。它开始变得非常混乱,尽管我付出了很多努力,但我知道这不能100%正确地工作。我希望用户输入“ BACK”尝试通过从缓存中请求回退一次发射。是否有更好的运营商或变压器在链中的上一个点回溯排放并将其重新发送回去?
public class Test {
public static void main(String[] args) {
final Scanner scanner = new Scanner(System.in);
final List<String> cache = new ArrayList<>();
final AtomicInteger cursorIndex = new AtomicInteger(-1);
Observable.just(
"What is your name?",
"What is your quest?",
"What is your favorite color?",
"What is the capital of Assyria?",
"What is the velocity of an unladen swallow?"
)
.doOnNext(cache::add)
.concatMap(q -> {
int cursor = cursorIndex.get();
if (cursor >= 0 && cursor < cache.size() - 2) {
return Observable.just(cache.get(cursor));
} else {
cursorIndex.incrementAndGet();
return Observable.just(q);
}
})
.doOnNext(System.out::println)
.concatMap(q -> Observable.create(s -> {
String answer = scanner.nextLine().trim();
if (answer.toUpperCase().equals("BACK")) {
cursorIndex.decrementAndGet();
}
s.onNext(answer);
s.onCompleted();
})
).filter(s -> !s.equals("BACK"))
.subscribe(q -> System.out.println("You said: " + q));
}
}
What is your name?
Sir Lancelot
You said: Sir Lancelot
What is your quest?
To seek the holy grail
You said: To seek the holy grail
What is your favorite color?
BACK
What is your quest?
我要做的就是将索引作为BehaviorSubject并在需要在问题之间进行切换时调用onNext:
Scanner scanner = new Scanner(System.in);
String[] questions = {
"What is your name?",
"What is your quest?",
"What is your favorite color?",
"What is the capital of Assyria?",
"What is the velocity of an unladen swallow?"
};
String[] cache = new String[questions.length];
BehaviorSubject<Integer> index = BehaviorSubject.create(0);
index
.observeOn(Schedulers.trampoline())
.concatMap(idx -> {
if (idx == questions.length) {
index.onCompleted();
return Observable.empty();
}
System.out.println(questions[idx]);
String answer = scanner.nextLine().trim();
if ("BACK".equals(answer)) {
index.onNext(Math.max(0, idx - 1));
return Observable.empty();
} else
if ("QUIT".equals(answer)) {
index.onCompleted();
return Observable.empty();
}
cache[idx] = answer;
index.onNext(idx + 1);
return Observable.just(answer);
})
.subscribe(v -> System.out.println("You said: " + v));
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句