Как сканировать рекурсивные структуры с помощью сопрограмм Kotlin?
Учитывая древовидную структуру и операцию для выборки дочерних узлов узла, например:
typealias NodeReference = URL
data class Node(
val data:Data,
val childrenList:List<NodeReference>)
suspend fun resolve(nodeRef:NodeReference) : Node
Вы знаете схему реализации функции краулера с подписью?
fun nodeList(rootNode:NodeReference) : List<Node> =
runBlocking(...) {
...
}
вернуть все узлы дерева с помощью сопрограмм Kotlin?
1 ответ
Решение
Для эффективного решения этой проблемы вам следует:
- Разрешить
rootRef: NodeReference
чтобы получитьrootNode: Node
- Рекурсивно асинхронно вызывать
nodeList
метод для всехchildren
изrootNode
- Жду результатов
- Объедините результаты и добавьте
rootNode
им
Вот как это сделать:
suspend fun nodesList(rootRef: NodeReference): List<Node> = coroutineScope {
val rootNode = resolve(rootRef) // 1
rootNode.childrenList
.map { async { nodesList(it) } } // 2
.awaitAll() // 3
.flatten() + rootNode // 4
}
Если вы хотите использовать текущий поток для выполнения nodesList
, вы можете сделать это следующим образом:
fun nodesListBlocking(rootRef: NodeReference): List<Node> = runBlocking { nodesList(rootRef) }