如何在Java中使Vertex MongoClient操作同步而不阻塞事件循环?

如何在Java中使Vertex MongoClient操作同步而不阻塞事件循环?,java,vert.x,Java,Vert.x,我正在尝试使用Vertx MongoClient将新文档保存到MongoDB,如下所示: MongoDBConnection.mongoClient.save("booking", query, res -> { if(res.succeeded()) { documentID = res.result(); System.out.println("MongoDB inserted successfully. + document ID is : "

我正在尝试使用Vertx MongoClient将新文档保存到MongoDB,如下所示:

MongoDBConnection.mongoClient.save("booking", query, res -> {
    if(res.succeeded()) {
        documentID = res.result();
        System.out.println("MongoDB inserted successfully. + document ID is : " + documentID);
    }
    else {
        System.out.println("MongoDB insertion failed.");
    }
});

if(documentID != null) {

    // MongoDB document insertion successful. Reply with a booking ID
    String resMsg = "A confirmed booking has been successfully created with booking id as " + documentID + 
        ". An email has also been triggered to the shared email id " + emailID;

    documentID = null;

    return new JsonObject().put("fulfillmentText", resMsg);
}
else {
    // return intent response
    documentID = null;
    return new JsonObject().put("fulfillmentText", 
        "There is some issues while booking the shipment. Please start afreash.");
}
上面的代码成功地将查询jsonObject写入MongoDB集合
booking
。但是,包含此代码的函数总是返回
,在预订装运时会出现一些问题。请启动刷新

发生这种情况可能是因为MongoClient
save()
处理程序“res”是异步的。但是,我想基于成功的
save()
操作和失败的save操作返回条件响应


如何在Vertx Java中实现它?

您的假设是正确的,您不需要等待来自数据库的异步响应。你能做的就是把它包装成这样的未来:

  public Future<JsonObject> save() {
    Future<JsonObject> future = Future.future();
    MongoDBConnection.mongoClient.save("booking", query, res -> {
      if(res.succeeded()) {
        documentID = res.result();
        if(documentID != null) {
          System.out.println("MongoDB inserted successfully. + document ID is : " + documentID);
          String resMsg = "A confirmed booking has been successfully created with booking id as " + documentID +
            ". An email has also been triggered to the shared email id " + emailID;
          future.complete(new JsonObject().put("fulfillmentText", resMsg));
        }else{
          future.complete(new JsonObject().put("fulfillmentText",
            "There is some issues while booking the shipment. Please start afreash."))
        }
      } else {
        System.out.println("MongoDB insertion failed.");
        future.fail(res.cause());
      }
    });
    return future;
  }
。。。然后,您可以调用save方法并根据结果提供不同的响应

public void addBooking(RoutingContext ctx){
    save().setHandler(h -> {
        if(h.succeeded()){
            ctx.response().end(h.result());
        }else{
            ctx.response().setStatusCode(500).end(h.cause());
        }
    })
}
您可以使用和(
io.vertx.reactivex.ext.mongo.MongoClient

以下是一段代码片段:

部署器

公共类部署器扩展了AbstractVerticle{
私有静态最终记录器=getLogger(Deployer.class);
@凌驾
公共作废开始(未来开始未来){
DeploymentOptions=newDeploymentOptions().setConfig(config());
JsonObject mongoConfig=新的JsonObject()
.put(“连接字符串”,
String.format(“mongodb://%s:%s@%s:%d/%s”,
config().getString(“mongodb.username”),
config().getString(“mongodb.password”),
config().getString(“mongodb.host”),
config().getInteger(“mongodb.port”),
config().getString(“mongodb.database.name”);
MongoClient client=MongoClient.createShared(vertx,mongoConfig);
RxHelper.deployVerticle(vertx、新预订存储(客户端)、选项)
.订阅(e->{
logger.info(“已成功部署”);
startFuture.complete();
},错误->{
logger.error(“部署失败”,错误);
startFuture.fail(错误);
});
}
}
预订存储

公共类BookingsStorage扩展了AbstractVerticle{
私有MongoClient MongoClient;
公共预订存储(MongoClient MongoClient){
this.mongoClient=mongoClient;
}
@凌驾
公开作废开始(){
var eventBus=vertx.eventBus();
消费者(“获取所有预订地址”,this::getAllBookings);
}
private void getAllBookings(消息消息消息){
rxFindWithOptions(“获取所有预订”集合、“新建JsonObject()、sortByDate())
.订阅(预订->{
//对预订做些什么
msg.回复(预订);
},
错误->{
失败(消息,错误);
}
);
}
私有无效失败(消息消息消息,可丢弃错误){
msg.fail(500,“发生意外错误:”+error.getMessage());
}
私有FindOptions sortByDate(){
返回new FindOptions().setSort(new JsonObject().put(“date”,1));
}
}
httprouterticle

//路由器处理程序内部:
vertx.eventBus().rxSend(“获取所有预订地址”,新JsonObject())
.订阅(预订->{
//对预订做些什么
},
e->{
//处理错误
}); 
public void addBooking(RoutingContext ctx){
    save().setHandler(h -> {
        if(h.succeeded()){
            ctx.response().end(h.result());
        }else{
            ctx.response().setStatusCode(500).end(h.cause());
        }
    })
}