我们有一个srings的列表,我们要循环执行。在循环中,我们将每个字符串传递给一个async调用。
问题是,在所有asysnc调用完成之前,循环就结束并退出了。
public void processMessage(Handler<AsyncResult<List<String>>> handler){
List<String> englishWords = new ArrayList(Arrays.asList("Hello","Where","How"));
List<String> spanishWords = new ArrayList();
for (int position = 0; position < englishWords.size(); position++) {
getLocalisedMessageAsync(englishWords.get(position), resultHandler -> {
if (resultHandler.succeeded()) {
spanishWords.add(resultHandler.result());
}
});
}
handler.handle(Future.succeededFuture(spanishWords));// this gets called before async calls
}
我们通过使用Promise对象解决了这个问题。
public void processMessage1(Handler<AsyncResult<List<String>>> handler){
List<String> englishWords = new ArrayList(Arrays.asList("Hello","Where","How"));
List<String> spanishWords = new ArrayList();
Promise<List<String>> promise = Promise.promise();
for (int position = 0; position < englishWords.size(); position++) {
int finalPosition = position;
getLocalisedMessageAsync(englishWords.get(position), resultHandler -> {
if (resultHandler.succeeded()) {
spanishWords.add(resultHandler.result());
if (finalPosition == englishWords.size() - 1) {
promise.complete(spanishWords);
}
}
});
}
promise.future().onComplete(completionHandler -> {
if (completionHandler.succeeded()) {
handler.handle(Future.succeededFuture(spanishWords));
}
});
}
但是否有一个简化的解决方案?在哪里我可以解决这个问题而不需要使用Promise对象?
你可以用CompletableFuturesCompletionStages来解决你的任务。
类似于
private CompletionStage<ResultHandler> getLocalisedMessageRH(String englishWord) {
CompletableFuture<String> future = new CompletableFuture<>();
getLocalisedMessageAsync(englishWord, future::complete);
return future;
}
private CompletionStage<String> getLocalisedMessageStage(String englishWord) {
return getLocalisedMessageRH(englishWord)
.thenApply(resultHandler -> {
if (resultHandler.succeeded()) {
return resultHandler.result();
} else {
throw <whatever unchecked exception>;
}
});
}
private CompletionStage<String> translate(CompletionStage<Void> base, String englishWord) {
return base.thenCompose(dummy ->
getLocalisedMessageStage(englishWord));
}
public void processMessage(Handler<AsyncResult<List<String>>> handler) {
List<String> englishWords = new Arrays.asList("Hello", "Where", "How");
List<String> spanishWords = new ArrayList();
CompletionStage<Void> step = CompletableFuture.completedStage(null);
for (int position = 0; position < englishWords.size(); position++) {
step = translate(step, englishWords.get(position))
.thenAccept(translation -> spanishWords.add(translation));
}
step
.thenRun(() -> handler.handle(Future.succeededFuture(spanishWords)))
.exceptionally(exc -> { do whatever must be done});
}
这样,完成阶段就会被串联起来,当失败时,链子就会停止,直到失败为止(如果这是你想要的)。