Kotlin协程和Java完全未来集成
通常我使用标准库从JavaKotlin协程和Java完全未来集成,kotlin,kotlin-coroutines,Kotlin,Kotlin Coroutines,通常我使用标准库从Java*futureAPI世界跳入Kotlin的suspend天堂 它对我来说非常有用,直到我遇到了Neo4J cursor API,在完成阶段我无法执行.wait(),因为它立即开始将数百万条记录提取到内存中 Kotlin way不适合我,就像这样: suspend fun query() { driver.session().use { session -> val cursor: StatementResultCursor = sessi
*future
API世界跳入Kotlin的suspend
天堂
它对我来说非常有用,直到我遇到了Neo4J cursor API,在完成阶段我无法执行.wait()
,因为它立即开始将数百万条记录提取到内存中
Kotlin way不适合我,就像这样:
suspend fun query() {
driver.session().use { session ->
val cursor: StatementResultCursor = session.readTransactionAsync {
it.runAsync("query ...", params)
}.await() // HERE WE DIE WITH OOM
var record = cursor.nextAsync().await()
while (record != null) {
val node = record.get("node")
mySuspendProcessingFunction(node)
record = cursor.nextAsync().await()
}
}
}
同时,Java API运行良好,我们逐个获取记录:
suspend fun query() {
session.readTransactionAsync { transaction ->
transaction.runAsync("query ...", params).thenCompose { cursor ->
cursor.forEachAsync { record ->
runBlocking { // BUT I NEED TO DO RUN BLOCKING HERE :(
val node = record.get("node")
mySuspendProcessingFunction(node)
}
}
}
}.thenCompose {
session.closeAsync()
}.await()
}
第二个选项对我来说很有用,但它非常难看——肯定不是Kotlin的方式,更重要的是,我需要使用runBlocking(但是这些块是在suspend函数中执行的)
我做错了什么?有更好的办法吗
UPD
尝试使用new Flow()功能执行此练习,但遗憾的是结果相同:
suspend fun query() {
session.readTransactionAsync { transaction ->
transaction.runAsync(query, params).thenApply { cursor ->
cursor.asFlow().onEach { record ->
val node = record.get("node")
mySuspendProcessingFunction(node)
}
}
}.thenCompose {
session.closeAsync()
}.await()
}
fun StatementResultCursor.asFlow() = flow {
do {
val record = nextAsync().await()
if (record != null) emit(record)
} while (record != null)
}