Vertx - Java - 在循环中使用Handlerslambda。

问题描述 投票:0回答:1

我们有一个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对象?

java asynchronous functional-programming vert.x
1个回答
2
投票

你可以用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});
}

这样,完成阶段就会被串联起来,当失败时,链子就会停止,直到失败为止(如果这是你想要的)。

© www.soinside.com 2019 - 2024. All rights reserved.