给出以下两个类:
public class Test {
public void call() {
MyClass myClass = new MyClass();
myClass.methodOne().subscribe(v -> {...});
}
}
public class MyClass {
public Observable<String> methodOne() {
Observable<String> response = Observable.fromFuture(this.methodTwo());
return response;
}
public CompletableFuture<String> methodTwo() {
CompletableFuture<String> response = new CompletableFuture<>();
KafkaProducerRecord<String, String> record = KafkaProducerRecord.create(...);
response.complete("initial value");
kafkaProducer.write(record, done -> {
if(done.succeeded()) {
response.complete("done");
}
else {
response.complete("not done");
};
);
return response;
}
}
kafkaProducer
是io.vertx.kafka.client.producer.impl.KafkaProducerImpl
的实例。
预期的行为是,在response.complete()
中调用MyClass.methodTwo()
时,response
的值将从methodTwo()
返回到methodOne()
。该值将在将来包装,并将在subscribe
中Test.call()
的处理程序中可用。
但是,由于异步处理,methodTwo()
将始终返回在vertx. kafkaProducer
的write方法之前设置的“初始值”。
即使稍后在处理程序中将response
设置为“完成”或“未完成”,该值也不会返回。
我尝试将methodTwo
中的代码更改为以下内容:
AsyncResult<RecordMetadata> res =
Single.create((SingleEmitter<AsyncResult<RecordMetadata>> emitter) ->
producer.write(record, result -> emitter.onSuccess(result)))
.blockingGet();
设想然后返回AsyncResult
中的值,但这会无限期阻塞。
解决这个问题的正确方法是什么?
谢谢
答案 0 :(得分:2)
您可以使用Vert.x Handler处理异步调用的结果。 异步调用完成后,您可以调用随结果传递的处理程序。
下面是与您的问题有关的小片段。
public class Test {
public void call() {
MyClass myClass = new MyClass();
myClass.methodTwo(f-> {
if (f.succeeded()) {
//do something with f.result()
}
else {
//handle;
}
});
}
}
public class MyClass {
public methodTwo(Handler<AsyncResult<String>> handler) {
KafkaProducerRecord<String, String> record = KafkaProducerRecord.create(...);
//response.complete("initial value");
kafkaProducer.write(record, done -> {
if(done.succeeded()) {
handler.handle("done");
}
else {
handler.handle("not done");
};
);
//return response;
}
}