Kotlin异步/等待语法,不会阻塞调用方 [英] Kotlin async/await syntax without blocking caller

查看:185
本文介绍了Kotlin异步/等待语法,不会阻塞调用方的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想弄清楚Kotlin是否可以替代我们当前处理异步代码的方式.现在,我们使用 CompletableFutures 处理异步代码.这是这种方法的示例:

I'd like to figure out if Kotlin can replace our current way of dealing with asynchronous code. Right now, we use CompletableFutures to handle asynchronous code. Here is an example of a such a method:

public void onBalanceRequest(Client client, String name) {
  db.fetchBalance(name)
    .thenAccept(balance -> {
       client.sendMessage("Your money: " + balance);
    });
}

这里重要的一点是 onBalanceRequest 是从主线程调用的,不能被阻塞.在内部, db.fetchBalance 运行异步操作并在完成时解决将来的问题,因此给定的调用不会阻塞主线程.

The important point here is that onBalanceRequest is called from the main thread, that must not be blocked. Internally, db.fetchBalance runs asynchronous operations and resolves the future on completion, so the given call is not blocking the main thread.

在审查了有关协同程序的Kotlin文档之后,我希望我们可以做一些像JavaScript的async/await之类的事情.例如,这是我们可以使用JavaScript进行的操作:

After reviewing the Kotlin docs regarding coroutines, I had hope that we can do something like JavaScript's async/await. For example, this is what we can do in JavaScript:

async function onBalanceRequest(client, name) {
  let balance = await db.fetchBalance(name);
  client.sendMessage("Your money: " + balance);
}

现在,我尝试将现有的API连接到Kotlin项目:

Now, I've tried to connect our existing API to a Kotlin project:

private fun onBalanceRequest(client: Client) = runBlocking {
    val money = db.fetchBalance(client.name)
    client.sendMessage("Your money: $money")
}

suspend fun fetchBalance(player: String): Double? {
    var result: Double? = null
    GlobalScope.launch {
        originalFetchBalance(player).thenAccept {
            result = it
        }
    }.join()
    return result
}

但是,由于我使用了 runBlocking ,所以 onBalanceRequest 的执行阻塞了主线程.因此,如果您可以通过Kotlin实现类似于async/await的功能,请问您.

However, since I used runBlocking, the execution of onBalanceRequest is blocking the main thread. So I'm aksing you, if I can achieve something similar to async/await with Kotlin.

谢谢.

推荐答案

如果您的JS函数是 async ,则相应的Kotlin函数应该是 suspend :

If your JS function is async, the corresponding Kotlin function should be suspend:

private suspend fun onBalanceRequest(client: Client) {
    val money = db.fetchBalance(client.name)
    client.sendMessage("Your money: $money")
}

不需要 await ,因为Kotlin是静态类型的,并且编译器已经知道哪些函数是 suspend 且需要特殊对待(尽管C#也是静态类型,则使用 async / await 模型来显示).

There's no need for await, because Kotlin is statically typed and the compiler already knows which functions are suspend and need to be treated specially (though C#, which is also statically typed, uses async/await model for explicitness).

请注意,只能从 suspend 函数直接调用它;如果您想发射后忘了",请使用启动:

Note that it can only be called directly from suspend functions; if you want to "fire-and-forget" it, use launch:

private fun onBalanceRequest(client: Client) = GlobalScope.launch {
    val money = db.fetchBalance(client.name)
    client.sendMessage("Your money: $money")
}

要使用您的 CompletableFuture 返回函数,请使用

And for using your CompletableFuture-returning functions, use kotlinx-coroutines-jdk8:

// should be suggested by IDE
import kotlinx.coroutines.future.await

suspend fun fetchBalance(player: String) = originalFetchBalance(player).await()

这篇关于Kotlin异步/等待语法,不会阻塞调用方的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆