简体   繁体   中英

Javascript Wrapping Callback as Promise Equivalent in Java 8 using CompletableFuture

In Javascript, I can wrap a callback as a promise as folllows:

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

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

So that I can call it with

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

And I would like to ask what is the equivalent of it in Java? Here is my code in Java, where I have no idea how to wrap the callback up.

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?
    }
}

So that I can call the code as follows:

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

I just think of a solution using CountDownLatch , though I don't think using CountDownLatch is a good idea, as it just block the thread from execution which wastes some resources. But it will be one possible solution for that.

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);
            }
        });
    }
}

Though the code does not look very nice, it is the first solution I can think of. Hope there are other better answers so that I can learn upon.

You won't be able to pass callback into CompletableFuture . I personally find it easier to handle promises in JavaScript and definitely more verbose in java .

In your example, I don't see the point of passing in the anonymous function (response) => { resolve(response); } (response) => { resolve(response); } to resolve the promise or future since CompletableFuture provides a get() method to resolve the CompletableFuture , which is called after your line of code

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

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

public class DataSubscriber {
    // Please update the name to reflect the correct semantic meaning
    public Response subscribeAsCallback(Request request) {
        // ... async operation 
        Response response = ...; 
        return response;
    }

    public CompletableFuture<Response> subscribeAsPromise(Request request) {
        return CompletableFuture.supplyAsync(this::subscribeAsCallback);
    }
}


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM