我尝试创建一个定期查询我的数据库的任务,将所有结果写入另一个状态,并且我想使用RxJava执行此操作。
我使用RxJava-JDBC查询我的数据库。这是代码的样子:
final Database db = Database.from(url);
db
.select("SELECT f1,f2 FROM mydata")
.autoMap(MyDatum.class)
.subscribe(
new Action1<MyDatum>() {
@Override
public void call(MyDatum t) {
state.add(t);
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable t) {
L.error("Task failed", t);
}
},
new Action0() {
@Override
public void call() {
state.makeAvailable();
}
}
);
当我订阅它然后它停止时,这是有效的。所以我使用Observable.interval
并使其工作:
Observable
.interval(10, TimeUnit.SECONDS)
.forEach(
new Action1<Long>() {
@Override
public void call(Long arg) {
db
.select("SELECT f1,f2 FROM mydata")
.autoMap(MyDatum.class)
.subscribe(
new Action1<MyDatum>() {
@Override
public void call(MyDatum t) {
state.add(t);
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable t) {
L.error("Task failed", t);
}
},
new Action0() {
@Override
public void call() {
state.makeAvailable();
}
}
);
}
}
);
但是我想知道我是否做错了将流嵌套在另一个中。
我考虑过使用flatMap
,但onComplete
永远不会被执行,因为interval
从不调用onComplete
。
我希望它能够进化并且不仅可以通过间隔而且可以通过传入事件来触发。
我在这里遗漏了什么吗? 感谢
答案 0 :(得分:1)
flatMap
和merge
是您要使用的运算符。首先,您应该避免在运算符的主体中订阅observable。而是使用flatMap并返回observable。这将为您订阅所有发出的可观测量。
为了手动触发查询,您可以合并PublishSubject
(documentation),您可以调用onNext
来推送事件并手动触发查询。将您的代码更改为类似的内容。
PublishSubject<Long> subject = PublishSubject.create();
Observable.merge(subject, Observable.timer(0, 1, TimeUnit.SECONDS))
.flatMap(new Func1<Long, Observable<MyDatum>>() {
@Override
public Observable<MyDatum> call(Long arg) {
return db
.select("SELECT f1,f2 FROM mydata")
.autoMap(MyDatum.class);
}}).subscribe(
new Action1<MyDatum>() {
@Override
public void call(MyDatum t) {
state.add(t);
}
},
new Action1<Throwable>() {
@Override
public void call(Throwable t) {
L.error("Task failed", t);
}
},
new Action0() {
@Override
public void call() {
state.makeAvailable();
}
}
);
// you can call onNext with any value to trigger a manual query
subject.onNext(999L);
这是一个演示此行为的简单RxJava代码段。
CountDownLatch l = new CountDownLatch(5);
PublishSubject<Long> subject = PublishSubject.create();
Observable.merge(subject, Observable.timer(0, 1, TimeUnit.SECONDS).take(3))
.flatMap((Long arg) -> {
System.out.println("tick: " + arg);
l.countDown();
return Observable.just(arg+10);
})
.forEach(System.out::println);
l.await(1, TimeUnit.SECONDS);
subject.onNext(999L);
l.await();
<强>输出强>
tick: 0
10
tick: 999
1009
tick: 1
11
tick: 2
12
答案 1 :(得分:1)
Before: 2015-06-08T15:57:00Z
Now: 2015-06-08T16:07:08.893Z
After: 2015-06-08T16:17:08.893Z
put items
{ Item: {hashAttributeName=1, dateField=2015-06-08T15:57:00Z} }
{ Item: {hashAttributeName=2, dateField=2015-06-08T16:07:08.893Z} }
expected conditional write with < to fail when they are equal
expected conditional write with < to fail when new is before
after all updates
{ Item: {hashAttributeName=1, dateField=2015-06-08T15:57:00Z} }
{ Item: {hashAttributeName=2, dateField=2015-06-08T16:17:08.893Z} }
和doOnNext
运算符在您的情况下非常有用。以下是如何使用这些运算符实现所描述的行为的示例:
doOnCompleted