如何在PlayFramework异步调用的Java Lambda BiFunction中传入多参数?
解决Play Framework中thenCombineAsync传多参数到render的问题
嘿,我明白你现在遇到的困惑了——thenCombineAsync确实只接受BiFunction,也就是只能处理两个异步操作的结果,但这并不影响你给render传入多个参数,咱们一步步来解决:
首先,先修正你代码里的一个小语法问题:thenCombineAsync的第二个参数应该是一个接收两个参数的lambda(对应两个CompletionStage的结果),你原来的写法里括号位置有点问题,正确的结构应该是:
return entryRepository.lookup(id) .thenCombineAsync(vendorsFuture, (entryOptional, vendors) -> { // 这里是HTTP渲染线程上下文 Entry c = entryOptional.get(); Form<Entry> entryForm = formFactory.form(Entry.class).fill(c); return ok(views.html.editForm.render(id, entryForm, vendors)); }, httpExecutionContext.current());
关键说明:
thenCombineAsync的作用就是组合两个异步任务的结果:第一个是entryRepository.lookup(id)返回的CompletionStage<Optional<Entry>>,第二个是vendorsFuture返回的CompletionStage<Vendors>(假设你的vendors是这个类型)。所以lambda里的两个参数entryOptional和vendors正好是这两个异步任务完成后的结果。- 你需要传给
render的id是方法的外部参数(应该在当前方法作用域内是可用的),所以直接在lambda里用就行,不需要通过BiFunction传递——lambda可以捕获外部作用域的变量(只要是final或者effectively final的)。 - 注意:直接调用
entryOptional.get()有风险,如果lookup(id)没找到对应的Entry,会抛出NoSuchElementException,建议做安全处理,比如:return entryOptional.map(c -> { Form<Entry> entryForm = formFactory.form(Entry.class).fill(c); return ok(views.html.editForm.render(id, entryForm, vendors)); }).orElseGet(() -> notFound("Entry not found"));
这样修改后,你就能顺利把id、entryForm和vendors三个参数传给render函数了,同时保持异步操作的正确性。
内容的提问来源于stack exchange,提问作者tikitaka
相关产品推荐
相关产品推荐

