Java 我的异步调用有什么问题?
我有一段代码:Java 我的异步调用有什么问题?,java,asynchronous,callback,asynccallback,Java,Asynchronous,Callback,Asynccallback,我有一段代码: public static void main(String[] args) throws UnirestException { ArrayList<Stock> listStock = getAllAvailableStocks("https://api.iextrading.com/1.0/ref-data/symbols"); //doing more actions after the one before, usi
public static void main(String[] args) throws UnirestException {
ArrayList<Stock> listStock
= getAllAvailableStocks("https://api.iextrading.com/1.0/ref-data/symbols");
//doing more actions after the one before, using the data from the listStock etc.
}
private static ArrayList<Stock> getAllAvailableStocks(String url) {
ArrayList<Stock> stocks = new ArrayList<Stock>();
Future<HttpResponse<JsonNode>> future = Unirest.get(url)
.header("accept", "application/json")
.asJsonAsync(new Callback<JsonNode>() {
public void failed(UnirestException e) {
System.out.println("The request has failed");
}
public void completed(HttpResponse<JsonNode> response) {
ObjectMapper objectMapper = new ObjectMapper();
try {
listStock = objectMapper.readValue(response.getRawBody(), new TypeReference<List<Stock>>(){});
} catch (Exception e) {
System.out.println("all is fucked");
}
return listStock;
}
public void cancelled() {
System.out.println("The request has been cancelled");
}
});
}
我是java的新手,我想做以下工作:
getAllAvailableStocks("https://api.iextrading.com/1.0/ref-data/symbols",new Callback<JsonNode>() {
public void failed(UnirestException e) {
System.out.println("The request has failed");
}
public void completed(HttpResponse<JsonNode> response) {
ArrayList<Stock> listStock = new ArrayList<Stock>();
ObjectMapper objectMapper = new ObjectMapper();
int code = response.getStatus();
System.out.println(code);
try {
listStock = objectMapper.readValue(response.getRawBody(), new TypeReference<List<Stock>>(){});
} catch (Exception e) {
}
System.out.println(listStock);
}
public void cancelled() {
System.out.println("The request has been cancelled");
}
});
}
private static Future<HttpResponse<JsonNode>> getAllAvailableStocks(String url,Callback<JsonNode> cb) {
return Unirest.get(url)
.header("accept", "application/json")
.asJsonAsync(cb);
}
1我想进行异步调用以获取并提取股票列表,只有在请求完成后,我才想在main方法中执行下一步操作
2如何从我构建的方法中提取数据,以便在方法之外使用数据
3如果我需要执行以下操作:
getAllAvailableStocks("https://api.iextrading.com/1.0/ref-data/symbols",new Callback<JsonNode>() {
public void failed(UnirestException e) {
System.out.println("The request has failed");
}
public void completed(HttpResponse<JsonNode> response) {
ArrayList<Stock> listStock = new ArrayList<Stock>();
ObjectMapper objectMapper = new ObjectMapper();
int code = response.getStatus();
System.out.println(code);
try {
listStock = objectMapper.readValue(response.getRawBody(), new TypeReference<List<Stock>>(){});
} catch (Exception e) {
}
System.out.println(listStock);
}
public void cancelled() {
System.out.println("The request has been cancelled");
}
});
}
private static Future<HttpResponse<JsonNode>> getAllAvailableStocks(String url,Callback<JsonNode> cb) {
return Unirest.get(url)
.header("accept", "application/json")
.asJsonAsync(cb);
}
或者诸如此类的东西,它使代码变得可怕,当我想在之后执行更多的异步请求时,我这里有一个回调地狱,有没有办法避免它?我在这里有什么选择?我认为你把时间和同步混淆了 如果你 想要做异步调用来获取并提取股票列表,只有在请求完成后我才想在main方法中做下一件事 然后您实际上想要执行同步调用 异步调用是执行请求,然后执行与请求无关的其他操作,然后在将来的某个时候获得请求的结果并处理它 要执行同步调用(这可能是您想要的),请尝试如下调整代码:
private static ArrayList<Stock> getAllAvailableStocks(String url) {
ArrayList<Stock> stocks = new ArrayList<Stock>();
Future<HttpResponse<JsonNode>> future = Unirest.get(url)
.header("accept", "application/json")
.asJsonAsync(new Callback<JsonNode>() {
public void failed(UnirestException e) {
System.out.println("The request has failed");
}
public void completed(HttpResponse<JsonNode> response) {
System.out.println("The request succeeded");
}
public void cancelled() {
System.out.println("The request has been cancelled");
}
});
HttpResponse<JsonNode> response = future.get(); // NOTE: This call is blocking until the request is finished
if (response != null && response.getStatus() == 200) {
JsonNode body = response.getBody();
// TODO Parse body and add items to `stocks`
}
return stocks;
}
ArrayList<Stock> stocks = getAllAvailableStocks(...);
stocks.forEach(x -> System.out.println(x));
该方法可按如下方式使用:
CompletableFuture<ArrayList<Stock>> stocksFuture = getAllAvailableStocks(...);
stocksFuture.thenAccept((stocks) -> {
// NOTE: This will be called after and only if the request succeeded
stocks.forEach(x -> System.out.println(x));
});
System.out.println("This is probably executed before the above request finished.");
Thread.sleep(10000); // If you are calling from your `main` method: Prevent JVM exit
在填充listStock之后,您需要从完成的块中调用下一段逻辑。以静态方法编写所有内容是非常罕见的,因此我认为您可能是java的真正新手-如果是这样,我建议您在开始研究未来和异步之前,先深入了解基本java,如果不是,我道歉。我不同意。OP需要一个异步管道-在调用完成后做一些事情就像使用CompletableFuture并添加thenApply调用一样简单。Boris你能给我看看你正在谈论的示例吗?@BoristheSpider谢谢你指出这一点。我已经添加了一个相应的例子。你的异步代码是相当破碎的-你忽略失败可以取消,所以一旦失败你的可完成的未来将永远不会完成。。。