如何在 Play Framework 2.x 操作中使用 MongoDB 异步 Java 驱动程序?

How to use MongoDB Async Java Driver in Play Framework 2.x action?

我想在 Play Framework 2 项目中使用 MongoDB Async Java Driver,MongoDB 异步 Java 驱动程序 return SingleResponseCallback。 我不知道如何在 Play 控制器中处理这种结果。

例如,如何 return 从播放控制器中的以下代码开始计数:

collection.count(
 new SingleResultCallback<Long>() {
  @Override
  public void onResult(final Long count, final Throwable t) {
      System.out.println(count);
  }
});

如何从 SingleResultCallback 获取结果,然后将其转换为 Promise?这是好方法吗?这种情况下的最佳做法是什么?

你必须自己解决承诺。请记住,Play promises 是 scala futures 的包装器,解决 future 的唯一方法是使用 scala Promises(不同于 play promises)(我知道,这有点令人困惑)。你必须做这样的事情:

Promise<Long> promise = Promise$.MODULE$.apply();
collection.count(
 new SingleResultCallback<Long>() {
   @Override
   public void onResult(final Long count, final Throwable t) {
     promise.success(count);
  }
});
return F.Promise.wrap(promise.future());

关于 Promise$.MODULE$.apply() 的事情就是从 java 访问 scala 对象的方式。

感谢@caeus 的回答,这是细节:

public F.Promise<Result> index() {
    return F.Promise.wrap(calculateCount())
            .map((Long response) -> ok(response.toString()));
}


private Future<Long> calculateCount() {
    Promise<Long> promise = Promise$.MODULE$.apply();

    collection.count(
            new SingleResultCallback<Long>() {
                @Override
                public void onResult(final Long count, final Throwable t) {
                    promise.success(count);
                }
            });

    return promise.future();
}

更简洁的解决方案是使用 F.RedeemablePromise<A>

public F.Promise<Result> index() {
    F.RedeemablePromise<Long> promise = F.RedeemablePromise.empty();

    collection.count(new SingleResultCallback<Long>() {
        @Override
        public void onResult(final Long count, final Throwable t) {
            promise.success(count);
        }
    });

    return promise.map((Long response) -> ok(response.toString()));
}