首页 > 解决方案 > 如何使用 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 协程返回树的所有节点?

标签: kotlincoroutinekotlin-coroutineskotlin-flowkotlinx.coroutines.channels

解决方案


为了有效地解决这个问题,你应该:

  1. 决心rootRef: NodeReference得到一个rootNode: Node
  2. 递归异步调用nodeList所有children的方法rootNode
  3. 等待结果
  4. 合并结果并将其添加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) }

推荐阅读