【问题标题】:Read value returned in CompletableFuture读取 CompletableFuture 中返回的值
【发布时间】:2019-06-18 14:16:10
【问题描述】:

来自某些 SDK 的函数返回给我一个 CompletableFuture。达到该值后如何正确读取该值。

我的代码:

CompletableFuture<Web3ClientVersion> web3clientCompletableFuture;
web3clientCompletableFuture = web3jNode.web3ClientVersion().sendAsync();

sendAsync() 代码(在 SDK 中):

public CompletableFuture<T> sendAsync() {
    return  web3jService.sendAsync(this, responseType);
}

我可以使用 get() 访问返回的数据,但这会使整个过程同步并阻塞 UI。

我检查了Android API Reference 上的函数签名,例如:

thenApply(Function<? super T, ? extends U> fn) 
handle(BiFunction<? super T, Throwable, ? extends U> fn) 

但似乎我需要一些代码示例。

[注意:我对 lambda 不是很熟悉]

【问题讨论】:

    标签: android completable-future


    【解决方案1】:

    这是 CompletableFuture 的 tutorial that has examples that show you how to use these powerful methods。如果您在处理未来后必须返回值,那么您想使用 thenApply() 是对的。但是如果你只是想处理未来而不返回任何东西,你应该使用 thenAccept() 和 thenRun()。还列出了其他方法并附有示例。

    这是一个简单地返回整数类型的 CompletableFuture 的示例:

    CompletableFuture<Integer> mynumber = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                mynumber = CompletableFuture.supplyAsync(() -> {
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        throw new IllegalStateException(e);
                    }
                    return 4 * 4;
                });
            }
    

    这里的 arg 是上述步骤的结果(CompletableFuture),在您的情况下是您从 SDK 接收的数据。您正在附加一个回调方法(thenApply())并做任何您想做的事情。根据您的实现,您可以附加多个 thenApply()。在这里,我调用了一个方法,该方法将获取结果并对其进行一些计算。

            CompletableFuture<Integer> willdoStuff = null;
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                willdoStuff = mynumber.thenApply(arg -> {
                    compute(arg);
                    return arg / 2;
                });
            }
    
    public void compute(int someInt){
            Toast.makeText(getApplicationContext(), "The result of the computation is" + someInt, Toast.LENGTH_LONG).show();
    }
    

    只需注释掉 sleep 代码即可在主线程中执行此代码。 Lambda 函数只是简单的输入和输出,{} 之前的参数是输入,{} 中的语句实际上是一个对参数(输入)进行操作的函数。您可能想就此提出不同的问题。

    【讨论】:

    • 感谢分享。我以前检查过文档。如果你对这些概念很清楚,你介意分享一个代码 sn-p 来解释我如何“读取数据”或“将数据传递给一个函数”,在我的场景中由 SDK 在 CompletableFuture 发送。跨度>
    • 我添加了一个示例。希望它很容易理解。
    • @The_Martian 我有一个类似的用例,但我正在尝试从数据库中获取数据并将其传递到 UI。我是 CompletableFuture 的新手,因为我试图将 AsyncTask [也 ExecutorService.submit() 替换为 .get()] 以将 CardViews 列表从 Room 数据库加载到 UI。没有任何运气,如果有任何想法或想法,将不胜感激:stackoverflow.com/questions/67294345/…
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-17
    • 2017-10-28
    • 1970-01-01
    • 2015-12-16
    • 2023-03-14
    • 2021-08-11
    • 2019-05-14
    相关资源
    最近更新 更多