简体   繁体   English

MongoDB异步Java驱动程序find()

[英]Mongodb async java driver find()

I have a webapp in which I have to return the results from a mongodb find() to the front-end from my java back-end. 我有一个Web应用程序,必须将mongodb find()的结果从Java后端返回到前端。 I am using the Async Java driver, and the only way I think I have to return the results from mongo is something like this: 我正在使用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;
}

Is this assumption right or there´s another way to do it? 这个假设是正确的还是还有另一种方法呢?

Asynchronous APIs (any API based on callbacks, not necessarily MongoDB) can be a true blessing for multithreaded applications. 对于多线程应用程序来说,异步API(任何基于回调的API,不一定是MongoDB)可能是真正的祝福。 But to really benefit from them, you need to design your whole application architecture in an asynchronous fashion. 但是要真正从中受益,您需要以异步方式设计整个应用程序体系结构。 This is not always feasible, especially when it is supposed to fit into a given framework which isn't built on callbacks. 这并不总是可行的,尤其是当它适合不基于回调的给定框架时。

So sometimes (like in your case) you just want to use an asynchronous API in a synchronous fashion. 因此,有时候(就像您的情况一样),您只想以同步方式使用异步API。 In that case, you can use the class CompletableFuture . 在这种情况下,您可以使用CompletableFuture类。

This class provides (among others) two methods <T> get() and complete(<T> value) . 此类提供(其中包括)两个方法<T> get()complete(<T> value) The method get will block until complete is called to provide the return value (should complete get called before get , get returns immediately with the provided value). 方法get will会阻塞,直到调用complete来提供返回值为止(应该在get之前调用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
}

The the get() -method of CompletableFuture also has an alternative overload with a timeout parameter . CompletableFuture的get()方法还有一个带有超时参数的替代重载 I recommend using this to prevent your program from accumulating hanging threads when the callback is not called for whatever reason. 我建议使用它来防止由于某种原因未调用回调时程序累积挂起的线程。 It will also be a good idea to implement your whole callback in a try { block and do the result.complete in the finally { block to make sure the result always gets resolved, even when there is an unexpected error during your callback. 最好在try {块中实现整个回调,并在finally {块中执行result.complete ,以确保即使在回调期间发生意外错误的情况下,结果也始终得到解决,这也是一个好主意。

Yes, you're right. 你是对的。

That's the correct behaviour of Mongo async driver (see MongoIterable.into ). 这是Mongo异步驱动程序的正确行为(请参阅MongoIterable.into )。

However, Why don't you use sync driver in this situation? 但是,为什么在这种情况下不使用同步驱动程序? Is there any reason to use async method? 有什么理由使用异步方法吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM