假设我们有类似的东西:
while (true) {
val job = Future { doSomething(); 1 }
val timeout = Future { Thread.sleep(1000); 2 }
val both = for (j <- job; t <- timeout) {
println("Done")
}
Await.result(both)
}
使用rx-java / scala?
的惯用解决方案是什么?更新:如果代码中没有明显的话,可以稍微澄清一下。
让 ts n 和 te n 为开始和<的时间戳分别是doSomething()
个职位的强>结束。
然后下一个作业应安排在 ts n + 1 = max(te n ,ts n + 1秒)
答案 0 :(得分:2)
在完成RxScala和Observables提供的所有可能性之后,我必须说这里可能存在一个根本问题:可观察的用户不应该控制新值的发射。可观察量是事件的来源,订户是被动消费者。否则,例如,一个订户可能会影响observable发送给其他订户的输出。
如果您仍想使用observables,这是我提出的最佳解决方案。它zip
可观察到ready
和计时器,以便在计时器和作业完成时发出新事件。
def run(job: () => Unit) {
val ready = Observable.create{ observer =>
for(
j <- future {job(); 1};
) observer.onNext();
}
Observable.timer(1 seconds).zip(ready).subscribe{ value =>
run();
}
}
run(doSomenthing);
答案 1 :(得分:0)
如果我正确理解了问题,你需要进行递归调度(因为它似乎不会从作业中发出任何值)。以下是如何使用RxJava&#39; s Scheduler.Worker
:
public class RecurringJob {
static Subscription runJob(Runnable run) {
Scheduler.Worker w = Schedulers.newThread().createWorker();
MultipleAssignmentSubscription mas = new MultipleAssignmentSubscription();
Action0 action = new Action0() {
@Override
public void call() {
try {
run.run();
mas.set(w.schedule(this, 1, TimeUnit.SECONDS));
} catch (Throwable t) {
t.printStackTrace();
w.unsubscribe();
}
}
};
mas.set(w.schedule(action, 1, TimeUnit.SECONDS));
return mas;
}
public static void main(String[] args) throws InterruptedException {
Subscription s = runJob(() -> System.out.println("Job"));
Thread.sleep(10000);
s.unsubscribe();
System.out.println("Job stopped");
Thread.sleep(3000);
System.out.println("Done.");
}
}