我尝试在play框架中组合CompletionStages,然后像ok()一样返回一个Result。这是我的设置:
AccountDao有两种方法:
public CompletionStage<Account> getUserByEmail(String email) {
return supplyAsync(() -> ebeanServer.find(Account.class).setUseCache(true).where().eq(EMAIL, email).findOne(), executionContext).thenApply(account -> {
return account;
});
}
public CompletionStage<Void> updateAccount(Account account) throws OptimisticLockException{
return runAsync(() -> {
ebeanServer.update(account);
}, executionContext);
}
然后我让我的控制器采取行动:
public CompletionStage<Result> editAccount() {
Map<String, String[]> form_values = request().body().asFormUrlEncoded();
return CompletableFuture.completedFuture(ok());
}
所以现在在我想要首先执行getUserByEmail的操作中,然后我想设置一些值并使用updateAccount方法更新它。如何在不阻止游戏背景的情况下结合这两个阶段?我用thenCompose尝试了不同的设置并结合但是我没有得到它......
这是我的一次尝试:
public CompletionStage<Result> editAccount() {
Map<String, String[]> form_values = request().body().asFormUrlEncoded();
accountDao.getUserByEmail(session().get("accountEmail")).thenCompose(x -> accountDao.updateAccount(x).thenApplyAsync(account -> {
return ok("Going to save account edits");
}, httpExecutionContext.current()));
return CompletableFuture.completedFuture(ok("Fehler am Ende"));
}
这里的问题是,我无法从之前访问帐户(x),因为我无法将其设置为函数...像这样:
public CompletionStage<Result> editAccount() {
Map<String, String[]> form_values = request().body().asFormUrlEncoded();
accountDao.getUserByEmail(session().get("accountEmail")).thenCompose(x -> {
//Update vars in x and then save to database
accountDao.updateAccount(x);
}.thenApplyAsync(account -> {
return ok("Going to save account edits");
}, httpExecutionContext.current()));
return CompletableFuture.completedFuture(ok("Fehler am Ende"));
}
这里我得到错误:此表达式的目标类型必须是一个功能接口,并且播放说我必须在函数末尾包含return语句!
我只是不明白......谢谢你的帮助!
@Marimuthu Madasamy这不是我想要的。在你的awnser我会更新帐户两次。在accountDao.updateAccount(帐户)和accountDao.saveAccount(帐户)中的etime;我想要这样的东西:
return accountDao.getUserByEmail("mail").thenCompose(account -> {
account.setName("NewName");
accountDao.save(account);
} .thenApplyAsync(voidInput -> {
return ok("Account saved");
}, httpExecutionContext.current()));
在这种情况下,只更新帐户一次,只返回httpExecutionContext
上的结果答案 0 :(得分:0)
如果我正确理解您的问题,您希望在updateAccount(account)
方法调用后访问(保存?)帐户。
由于updateAccount
方法返回CompletionStage<Void>
,当您在此阶段调用thenApplyAsync
时,输入类型将只是Void
,而不是Account
。但是,使用以下代码,您仍然可以访问从getUserByEmail
返回的帐户,假设updateAccount
通过您的文字变更帐户&#34;更新x中的变量&#34;:
public CompletionStage<Result> editAccount() {
return accountDao
.getUserByEmail(email)
.thenCompose(account -> accountDao.updateAccount(account)
.thenApplyAsync(voidInput -> {
// here you still have access to the `account` from `getUserByEmail` method
accountDao.saveAccount(account);
return ok("Account saved");
}, httpExecutionContext.current());
}
答案 1 :(得分:0)
好的,我在Marimuthu Madasamy的支持下找到了我自己的芒果!谢谢。我试图解释一下。首先是代码:
public CompletionStage<Result> editAccount() {
Map<String, String[]> form_values = request().body().asFormUrlEncoded();
return accountDao.getUserByEmail(session().get("accountEmail")).thenApply(account -> {
System.out.println("Async get Account / "+Thread.currentThread());
account.setCompany(form_values.get("company")[0]);
return accountDao.updateAccount(account);
}).thenApplyAsync(account -> {
System.out.println("Async resutl / "+Thread.currentThread());
return ok("Account saved normal");
}, httpExecutionContext.current()).exceptionally(e ->{
System.out.println("Async exception / "+Thread.currentThread());
System.out.println(e.getLocalizedMessage());
return ok(e.getLocalizedMessage());
});
}
好的,首先我执行accountDao.getUserByEmail(),因为你可以在我的awnser顶部看到它返回CompletionStage并在我的数据库执行上下文中执行。接下来使用thenApply我得到结果并执行下一个Async mehtod。我使用thenApplyAsync的thenApply instand,因此下一次调用也会使用数据库执行上下文执行,而不会显式设置它。在accountDao.updateAccount()之后我执行httpExecutionContext上的下一个阶段来重放结果或者异常退出!我真的希望它很清楚并帮助一个人!