Mongodb异步java驱动程序find()

时间:2015-10-21 10:54:43

标签: java mongodb asynchronous

我有一个webapp,我必须将mongodb find()的结果从我的java后端返回到前端。 我正在使用Async Java驱动程序,我认为我必须从mongo返回结果的唯一方法是这样的:

public String getDocuments(){
  ...
  collection.find(query).map(Document::toJson)
        .into(new HashSet<String>(), new SingleResultCallback<HashSet<String>>() {
            @Override
            public void onResult(HashSet<String> strings, Throwable throwable) {
              // here I have to get all the Json Documents in the set,
              // make a whole json string and wake the main thread
            }
        });
  // here I have to put the main thread to wait until I get the data in
  // the onResult() method so I can return the string back to the front-end
  ...
  return jsonString;
}

这种假设是正确的还是有另一种方法可以做到这一点?

2 个答案:

答案 0 :(得分:6)

异步API(任何基于回调的API,不一定是MongoDB)对于多线程应用程序来说都是真正的祝福。但要真正从中受益,您需要以异步方式设计整个应用程序架构。这并不总是可行的,特别是当它应该适合不是基于回调构建的给定框架时。

所以有时候(就像你的情况一样)你只想以同步的方式使用异步API。在这种情况下,您可以使用课程CompletableFuture

此类提供(以及其他)两种方法<T> get()complete(<T> value)。方法get将阻塞,直到调用complete来提供返回值(complete之前应调用getget会立即返回提供的值)

public String getDocuments(){
  ...
  CompletableFuture<String> result = new CompletableFuture<>(); // <-- create an empty, uncompleted Future

  collection.find(query).map(Document::toJson)
        .into(new HashSet<String>(), new SingleResultCallback<HashSet<String>>() {
            @Override
            public void onResult(HashSet<String> strings, Throwable throwable) {
              // here I have to get all the Json Documents in the set and
              // make a whole json string

              result.complete(wholeJsonString); // <--resolves the future
            }
        });

  return result.get(); // <-- blocks until result.complete is called
}

CompletableFuture的get() - 方法也has an alternative overload with a timeout parameter。我建议使用它来防止程序在由于某种原因未调用回调时累积挂起的线程。在try {块中实现整个回调也是一个好主意,并在result.complete块中执行finally {以确保结果始终得到解决,即使存在回调期间出现意外错误。

答案 1 :(得分:1)

是的,你是对的。

这是Mongo异步驱动程序的正确行为(请参阅MongoIterable.into)。

但是,为什么在这种情况下你不使用同步驱动程序?有没有理由使用异步方法?