gpt4 book ai didi

java - 将多个 promise 组合成一个 promise PlayFramework 2.4

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:43:27 25 4
gpt4 key购买 nike

我正在尝试学习 Play Framework 2.4。我正在尝试获取使用 Promise 异步访问不同网页所需的时间。以下是相关代码:

final long start = System.currentTimeMillis();

F.Function<WSResponse,Long> timing = new F.Function<WSResponse, Long>() {
@Override
public Long apply(WSResponse wsResponse) throws Throwable {
return System.currentTimeMillis()-start;
}
};
F.Promise<Long> google = ws.url("http://www.google.com").get().map(timing);
F.Promise<Long> yahoo = ws.url("http://www.yahoo.com").get().map(timing);
F.Promise<Long> bing = ws.url("http://www.bing.com").get().map(timing);

如您所见,我正在使用 get 函数获取请求的页面并将结果放入 Future Promise 中。然后我将它转换/映射到长。我无法做的是如何将这三个 promise 合二为一,一旦所有三个 promise 都被兑现,将其转换/映射到 json 并返回结果。在较早版本的 Play 中,它可以由 F.Promise.waitAll(google,yahoo,bing).map(...) 完成。但是我无法在 Play 2.4 中执行此操作。请指教

EDIT1:根据下面的答案,我使用了如下序列:

return F.Promise.sequence(google, yahoo, bing).map(new F.Function<List<Long>, Result>() {
@Override
public Result apply(List<Long> longs) throws Throwable {
Map<String, Long> data = new HashMap<String, Long>();
data.put("google", google.get());
data.put("yahoo", yahoo.get());
data.put("bing", bing.get());
return ok(Json.toJson(data));
}
});

但是,我收到无法解析 google.get() 方法并且无法应用 Json 的错误。我在这里缺少什么?

编辑 2. 使用 return ok((JsonNode) Json.toJson((Writes<Object>) data)); 修复了 Json 错误但是,我仍然无法解决早期的错误,即 google.get() 方法无法在 data.put("google", google.get()); 行中解决。

编辑 3. Play2.4 似乎没有 get() 方法,该方法在 Promise 被赎回后返回其值。那我该用什么?

最佳答案

waitAll已替换为 F.Promise.sequence .

来自docs

public static <A> F.Promise<java.util.List<A>> sequence(java.lang.Iterable<F.Promise<A>> promises)

Combine the given promises into a single promise for the list of results. The sequencing operations are performed in the default ExecutionContext.

Parameters: promises - The promises to combine

Returns: A single promise whose methods act on the list of redeemed promises

更新

关于后半题,不用打.get()因为 promise 已经完成。

事实上,您可以去掉单独的 promise 变量,直接将它们传递到序列中。结果列表将包含相同顺序的结果(在这种情况下,首先是 Google,然后是 Yahoo,然后是 Bing)。

整个事情看起来应该是这样的:

package controllers;

import java.util.HashMap;
import java.util.Map;
import play.libs.F;
import play.libs.Json;
import play.libs.ws.WS;
import play.libs.ws.WSResponse;
import play.mvc.Controller;
import play.mvc.Result;
import play.mvc.Results;

public class Application extends Controller {

public F.Promise<Result> index() {
final long start = System.currentTimeMillis();
final F.Function<WSResponse,Long> timing = response -> System.currentTimeMillis() - start;

return F.Promise.sequence(WS.url("http://www.google.com").get().map(timing),
WS.url("http://www.yahoo.com").get().map(timing),
WS.url("http://www.bing.com").get().map(timing))
.map(list -> {
Map<String, Long> data = new HashMap<>();
data.put("google", list.get(0));
data.put("yahoo", list.get(1));
data.put("bing", list.get(2));
return data;
})
.map(Json::toJson)
.map(Results::ok);
}

}

最后,由于 Play 2.4 需要 Java 8,这是一个使用 lambda 的好机会!

关于java - 将多个 promise 组合成一个 promise PlayFramework 2.4,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31021939/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com