我已经开始玩项目反应堆了,并希望将我们的API之一移动到被动的做事方式。我想知道什么是处理像ListenableFuture这样的东西。
就我而言,我正在使用Cassandra,当我调用session.executeAsync()时,这会返回一个ResultSetFuture,它扩展了ListenableFuture。 下面是我现在编写的代码示例,我似乎并不满意将ListenableFuture暴露给客户。
public Mono<ListenableFuture<Void> save(Publisher<AccountDTO> accountPublisher) {
return Mono.just(accountPublisher)
.map(accountDTO -> {
Account accountEntity = modelMapper.map(accountDTO, Account.class);
return mappingManager.mapper(Account.class).saveAsync(accountEntity);
})
.retry(1)
.doOnError(throwable -> log.error("Unable to create account "))
.mapError(throwable -> new MyCustomException("")
}
我的问题是,暴露ListenableFuture是一个好习惯,我个人不想把这样的东西送回他们可以阻止的客户端。有没有更好的方法在项目反应堆中处理这个问题,我可以返回Mono?
答案 0 :(得分:3)
您可以使用ListenableFuture<Void>
工厂方法轻松桥接Mono<Void>
异步API,而不是公开Mono.create()
。该方法采用Consumer<Sink>
,您将其作为lambda提供:
sink.success()
的未来添加成功侦听器(因为没有实际值,或者您也可以使用侦听器收到的success(aVoid)
值调用Void
)sink.error(failure)
这就是它!请参阅create
上的参考文档(尽管有人提到Flux
版本,由于必须处理多个值而稍微复杂一点):http://projectreactor.io/docs/core/release/reference/docs/index.html#producing.create
答案 1 :(得分:1)
发布我在@Simon上面指导编码的代码段。
@Override
public void onTaskTypePick()
{
getSupportFragmentManager().popBackStack();
}
答案 2 :(得分:0)
在使用lambdas的Java 8中,如果您正在寻找Simon使用ListenableFutures创建Flux的答案的实现,
Flux.create(fluxSink -> {
future.addCallback(
result -> {
fluxSink.next(result);
fluxSink.complete();
},
ex -> fluxSink.error(ex));
});
答案 3 :(得分:0)
由于这篇文章比较老,两个库的API都已经成熟,可以提供一种更简单的解决方案。
一个人可以简单地将library Sheetfu与default CompletableFuture completable()结合使用。
这里是改编自public static Mono fromFuture(CompletableFuture<? extends T> future)
的示例public void sendToKafka(final MyOutputData data) {
final ProducerRecord<String, String> record = createRecord(data);
CompletableFuture<SendResult<Integer, String>> future = template.send(record).completable();
Mono<SendResult<Integer, String>> mono = Mono.fromFuture(future)
.doOnSuccess((result) -> handleSuccess(data))
.doOnError((ex) -> handleFailure(data, record, ex))
.doFinally((signalType) -> { if(signalType == SignalType.CANCEL) future.cancel(true); });
mono.subscribe();
}
请注意,取消Mono时,未来不会取消,但是可以通过使用Note from Reactor JavaDocs来检查doFinally(Consumer)并调用SignalType.CANCEL来获得该行为。