使用CompletableFuture在Java 8中将JavaScript包装回叫为Promise

问题描述

在Javascript中,我可以将回调包装为如下承诺:

function subscribeAsCallback(request,callback) {
    // ... async operation
    const response = ...; 
    callback(response); 
}

function subscribeAsPromise(request) {
    return new Promise((resolve,reject) => {
        subscribeAsCallback(request,(response) => {
            resolve(response);
        });
    });
}

这样我就可以打电话给

subscribeAsPromise(request).then(response => {
   // handling response logic
});

我想问在Java中相当于什么?这是我在Java中的代码,在那里我不知道如何包装回调。

public class DataSubscriber {
    public void subscribeAsCallback(Request request,Consumer<Response> consumer) {
        // ... async operation 
        Response response = ...; 
        consumer.accept(response); 
    }

    public CompletableFuture<Response> subscribeAsPromise(Request request) {
        // ... ? 
        // what is the equivalent of its Java version?
    }
}

这样我可以按以下方式调用代码:

dataSubscriber.subscribeAsPromise(request).thenApply(response -> {
   // handling response logic
});

解决方法

我只是考虑使用CountDownLatch的解决方案,尽管我不认为使用CountDownLatch是一个好主意,因为它只是阻塞了执行线程,从而浪费了一些资源。但这将是解决该问题的一种方法。

public class DataSubscriber {
    public void subscribeAsCallback(Request request,Consumer<Response> consumer) {
        // ... async operation 
        Response response = ...; 
        consumer.accept(response); 
    }

    public CompletableFuture<Response> subscribeAsPromise(Request request) {        
        return CompletableFuture.supplyAsync(() -> {
            try {
                final Response[] responeResult = { null }; 
                CountDownLatch latch = new CountDownLatch(1);
                subscribeAsCallback(request,new Consumer<Response>() {
                    public void accept(Response response) {
                        responeResult[0] = response;
                        latch.countDown(); 
                    }
                });

                latch.await();
                return responseResult[0]; 
            } catch (Exception ex) {
                throw new RuntimeException(ex);
            }
        });
    }
}

尽管代码看起来不是很好,但这是我能想到的第一个解决方案。希望还有其他更好的答案,以便我可以学习。

,

您将无法将callback传递到CompletableFuture中。我个人发现,在promises中处理JavaScript更容易,在java中肯定更冗长。

在您的示例中,我看不到将匿名函数(response) => { resolve(response); }传递到resolvepromise的{​​{1}}的意义,因为future提供了CompletableFuture方法来解析get(),该方法在您的代码行之后被调用

CompletableFuture
CompletableFuture future = dataSubscriber.subscribeAsPromise(request).thenApply(response -> {
   // handling response logic
});

// do this to "resolve" the future
future.get();

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...