有没有办法在控制器外部使用await()机制?
我不希望代码在控制器中进行异步调用,而是将该代码放在可由多个控制器重用的服务类中,但是,由于该方法受到保护,因此无法在控制器外调用等待.
例如在控制器中:
ServiceClass service = new My ServiceClass();
MyObject myObject= service.getMeAnObject();
render(myObject);
Run Code Online (Sandbox Code Playgroud)
和服务类:
public class ServiceClass
{
...
public MyObject getMeAnObject()
{
String url = "http://...";
Promise<HttpResponse> promise = url(url).getAsync();
// do something here similar to await in a controller
// that suspends the code waiting for the response
// to be retrieved
HttpResponse response = promise.get();
return buildMyObjectFromResponse(reponse);
}
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法实现这样的目标?
谢谢你的帮助.
编辑:我遵循Pere的建议,并使服务类实现Controller,但是它有效,必须增强使用它的控制器.我发现完成这项工作的唯一方法是至少在调用控制器类中调用await方法().
但是,我仍然没有验证代码实际上是暂停的.
编辑2:我从google小组获得的一个建议是我应该尝试在控制器中进行等待,所以也许更好的解决方案是让服务返回Promise并让控制器等待这个然后就没有了我的方式是todo吗?
例如在控制器中:
ServiceClass service = new My ServiceClass();
Promise<MyObject> promise = service.getMeAnObject();
MyObject myObject = await(promise);
render(myObject);
Run Code Online (Sandbox Code Playgroud)
和服务类:
public class ServiceClass
{
...
public Promise<MyObject> getMeAnObject()
{
String url = "http://...";
// Somehow Build a Promise<MyObject>
}
...
}
Run Code Online (Sandbox Code Playgroud)
}
到目前为止,这是我认为最好的方法,除非在 Play 实例中管理单独的线程池存在问题。
我已经举例说明了 Play 在 WSAsync.WSAsyncRequest 类中所做的事情,这似乎有效。
本质上,等待是在控制器内完成的,但是服务类返回我期望服务返回的对象的 Promise,这很好,因为我不知道如何在控制器级别检索该对象的详细信息。
在控制器中:
ServiceClass service = new My ServiceClass();
Promise<MyObject> promise = service.getMeAnObject();
MyObject myObject = await(promise);
render(myObject);
Run Code Online (Sandbox Code Playgroud)
以及服务等级:
public class ServiceClass
{
public Promise<MyObject> getMeAnObject()
{
String url = "http://...";
return execute(WS.url(url).getAsync());
}
private Promise<MyObject> execute(final Promise<HttpResponse> promise)
{
try
{
final Promise<MyObject> smartFuture = new Promise<MyObject>();
ScheduledThreadPoolExecutor executor = MyAppThreadPools.getServiceThreadPool();
executor.submit(new Runnable()
{
@Override
public void run()
{
try
{
smartFuture.invoke(new MyObject(promise.get()));
}
catch (Throwable e)
{
smartFuture.invokeWithException(e);
}
}
});
return smartFuture;
}
catch (Exception e)
{
throw new RuntimeException(e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
所以这似乎暂时解决了我的问题。
谢谢大家。
| 归档时间: |
|
| 查看次数: |
2242 次 |
| 最近记录: |