Kotlin协程和Java Completable未来集成

时间:2019-06-01 04:14:29

标签: kotlin kotlin-coroutines

通常,我正在使用标准的kotlin-jdk8库从Java *future API世界跳入Kotlin的suspend天堂。

它对我来说非常有用,直到遇到Neo4J游标API,在完成阶段我无法完成.await(),因为它立即开始将数百万条记录提取到内存中。

科特琳的方式对我不起作用,像这样:

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

与此同时,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 尝试使用新的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)
}

0 个答案:

没有答案