我遇到问题,我无法将处理程序结果存储到Json Array中。每次数组都为空。我试图使用Future但它仍然是同样的问题,这是我的代码:
static void getCaraReferTypeDocBin(RoutingContext routingContext){
String ids = routingContext.request().getParam("ids");
logger.debug(ids);
String[] idsArray = ids.split(",");
JsonArray caraRefTypeDocBin = new JsonArray();
for (int i = 0; i <idsArray.length ; i++) {
GET.getCaraTypeDocBin(Integer.parseInt(idsArray[i]), res->{
if (res.succeeded()){
logger.debug(res.result());
caraRefTypeDocBin.add(res.result());
}else{
logger.debug(res.cause().getMessage());
}
});
}
logger.debug(caraRefTypeDocBin);
}
这是getCaraReferTypeDocBin
实施:
public static void getCaraTypeDocBin(int id ,Handler<AsyncResult<JsonArray>> resultHandler) {
JsonArray pIn = new JsonArray();
pIn.add(new JsonObject().put("pos", 2).put("type", OracleTypes.NUMBER).put("val", id));
JsonArray pOut = new JsonArray().add(new JsonObject().put("pos", 1).put("type", OracleTypes.CURSOR));
DB.cursor(SQL.LIST_CARA_TYPE_DOC_BIN,pIn,pOut, res -> {
if (res.succeeded()) {
try {
resultHandler.handle(Future.succeededFuture(res.result().getJsonArray("1")));
}catch (Exception e){
logger.error(e);
resultHandler.handle(Future.failedFuture(Error.ERROR_OCCURED.toString()));
}
} else {
resultHandler.handle(Future.failedFuture(res.cause().getMessage()));
}
});
}
答案 0 :(得分:2)
在异步系统中,带有期货的API应该写成这样的东西:
private Future<String> loadFromDb() {
Future<String> f = Future.future();
//some internal loading from db
String result = "fromDb";
//when loading completes, pass it to future result
f.complete(result);
return f;
}
它的用途:
private void handleSo(RoutingContext routingContext) {
loadFromDb()
.map(new Function<String, JsonArray>() {
@Override
public JsonArray apply(String fromDb) {
//map to json
return new JsonArray(...);
}
})
.setHandler(
new Handler<AsyncResult<JsonArray>>() {
@Override
public void handle(AsyncResult<JsonArray> result) {
routingContext.response().end(result.result().toString());
}
}
);
}
你正在使用期货错误。你的例子很简单,你没有异步链(其中结果根据以前的结果计算等),所以相反期货,你可以简单地使用回调:
private void loadFromDb(Handler<String> handler) {
String result = "fromDb";
handler.handle(result);
}
private void handleSo(RoutingContext routingContext) {
loadFromDb(new Handler<String>() {
@Override
public void handle(String fromDb) {
routingContext.response().end(new JsonArray(...).toString());
}
});
}
更新您需要从多个异步调用doc收集结果。不知道如何用回调样式api实现它。但对于期货而言,这不是问题:
private void handleSo(RoutingContext routingContext) {
List<Future> futures = new ArrayList<>();
for (int i = 0; i < 10; i++) {
//make 10 async calls
futures.add(loadFromDb()
.map(new Function<String, JsonObject>() {
@Override
public JsonObject apply(String fromDb) {
return new JsonObject().put("data", fromDb);
}
}));
}
CompositeFuture.all(futures)
.map(new Function<CompositeFuture, JsonArray>() {
@Override
public JsonArray apply(CompositeFuture compositeFuture) {
JsonArray array = new JsonArray();
List<JsonObject> jsons = compositeFuture.result().list();
jsons.forEach(jsonObject -> array.add(jsonObject));
return array;
}
})
.setHandler(new Handler<AsyncResult<JsonArray>>() {
@Override
public void handle(AsyncResult<JsonArray> res) {
routingContext.response().end(res.result().toString());
}
});
}
答案 1 :(得分:0)
GET.getCaraTypeDocBin()
异步运行,对吗?我认为那里有一些耗时的东西,比如点击远程API?所以循环将在几毫秒内运行,启动所有请求,然后“logger.debugs
”将发生,然后回调才会开始caraRefTypeDocBin.add(res.result());
如果我是对的,你应该看到在空数组之前记录结果。