1

I am having some strange trouble with the method await(Future future) of the Controller.

Whenever I add an await line anywhere in my code, some GenericModels which have nothing to do with where I placed await, start loading incorrectly and I can not access to any of their attributes.

The wierdest thing is that if I change something in another completely different java file anywhere in the project, play will try to recompile I guess and in that moment it starts working perfectly, until I clean tmp again.

4

1 回答 1

1

当您在控制器中使用 await 时,它会增强字节码以将单个方法分成两个线程。这很酷,但绝对是 Play1 的“黑魔法”之一。但是,这是 Play 经常表现得很奇怪并且需要重新启动(或者如您所见,需要更改一些代码)的地方 - 另一个可能表现得很奇怪的地方是当您更改 Model 类时。

http://www.playframework.com/documentation/1.2.5/asynchronous#SuspendingHTTPrequests

为了更容易处理异步代码,我们引入了延续。延续允许您的代码透明地暂停和恢复。因此,您以非常必要的方式编写代码,例如:

public static void computeSomething() { Promise delayResult = veryLongComputation(...); 字符串结果 = 等待(延迟结果);渲染(结果);}

实际上,在这里,您的代码将分 2 步执行,分 2 个不同的线程执行。但正如您所见,它对您的应用程序代码非常透明。

使用 await(...) 和延续,您可以编写一个循环:

 public static void loopWithoutBlocking() {
     for(int i=0; i<=10; i++) { 
          Logger.info(i);
          await("1s");
     }
     renderText("Loop finished"); } 

并且仅使用 1 个线程(这是开发模式下的默认设置)来处理请求,Play 能够同时为多个请求同时运行这些循环。


要回复您的评论:

 public static void generatePDF(Long reportId) {
    Promise<InputStream> pdf = new ReportAsPDFJob(report).now();
    InputStream pdfStream = await(pdf);
    renderBinary(pdfStream);

而 ReportAsPDFJob 只是一个覆盖 doJobWithResult 的 play Job 类 - 所以它返回对象。有关工作的更多信息,请参阅http://www.playframework.com/documentation/1.2.5/jobs

调用job.now()返回一个未来/承诺,您可以像这样使用它:await(job.now())

于 2013-04-21T14:06:19.617 回答