我有一个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;
}
这种假设是正确的还是有另一种方法可以做到这一点?
答案 0 :(得分:6)
异步API(任何基于回调的API,不一定是MongoDB)对于多线程应用程序来说都是真正的祝福。但要真正从中受益,您需要以异步方式设计整个应用程序架构。这并不总是可行的,特别是当它应该适合不是基于回调构建的给定框架时。
所以有时候(就像你的情况一样)你只想以同步的方式使用异步API。在这种情况下,您可以使用课程CompletableFuture
。
此类提供(以及其他)两种方法<T> get()
和complete(<T> value)
。方法get
将阻塞,直到调用complete
来提供返回值(complete
之前应调用get
,get
会立即返回提供的值)
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)