import scala.collection.JavaConverters._
import scala.concurrent.Await
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.io._
import org.json.JSONObject
import org.json4s.native.Serialization._
import org.mongodb.scala._
import org.mongodb.scala.model.Filters._
import org.mongodb.scala.model.Updates._
import org.mongodb.scala.Document._
import com.mongodb.MongoCredential
import com.mongodb.async.client.MongoClientSettings
import com.mongodb.connection.ClusterSettings
import com.mongodb.client.model.UpdateOptions
import com.mongodb.client.result.UpdateResult
import scala.concurrent.ExecutionContext
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration.Duration
import scala.concurrent._
import scala.util._
object Async {
def main(args: Array[String]): Unit =
{
var mongoClient: MongoClient = null
val credential: MongoCredential = MongoCredential.createScramSha1Credential("user", "database", "password".toArray)
val clusterSettings: ClusterSettings = ClusterSettings.builder().hosts(List(new ServerAddress("localhost:27017")).asJava).build()
val settings: MongoClientSettings = MongoClientSettings.builder().codecRegistry(MongoClient.DEFAULT_CODEC_REGISTRY).clusterSettings(clusterSettings).credentialList(List(credential).asJava).build()
mongoClient = MongoClient(settings)
val db: MongoDatabase = mongoClient.getDatabase("database")
var collection: MongoCollection[Document] = db.getCollection("collectionName")
var output : Document = Document()
var query: Document = Document()
var projection: Document = Document()
output = find(query, projection, collection)
println(output)
}
def find(query: Document, projection: Document, collectionName : MongoCollection[Document]) : Document = {
var previousDoc : Document = Document()
var future = collectionName.find(equal("_id", query)).projection(projection).toFuture()
collectionName.find(equal("_id", query)).projection(projection).subscribe(
(data: Document) => { previousDoc = data },
(error: Throwable) => println(s"Query failed: ${error.getMessage}"),
() => println("Done")
)
Await.result(future, Duration(100000, MILLISECONDS))
previousDoc
}
}
我在mongodb中执行了find操作,这里是使用scala的代码。但是上面代码的执行是非阻塞的,因此在从mongodb检索数据之前,进程结束。我想知道,如何在不使用Await和Thread.sleep函数的情况下执行mongodb操作时控制非阻塞。
答案 0 :(得分:0)
Future是一种占位符对象,您可以为尚不存在的结果创建该占位符对象。通常,Future的结果是同时计算的,以后可以收集。
Scala提供组合器,例如flatMap,foreach和过滤器,用于以非阻塞方式组成期货。
你可以做这样的事情
future.flatMap{
response => //do something when the response is available ...
}
用于补偿
for {
response <- fuurure
} yield{
//do something when the response is available ...
}
请参阅此文档了解期货和承诺 http://docs.scala-lang.org/overviews/core/futures.html