此代码基于Coroutines guide example: Fan-out
val inputProducer = produce<String>(CommonPool) {
(0..inputArray.size).forEach {
send(inputArray[it])
}
}
val resultChannel = Channel<Result>(10)
repeat(threadCount) {
launch(CommonPool) {
inputProducer.consumeEach {
resultChannel.send(getResultFromData(it))
}
}
}
创建可提供结果的Sequence<Result>
的正确方法是什么?
答案 0 :(得分:3)
您可以从.iterator()
获取通道ReceiveChannel
,然后将该通道迭代器包装到Sequence<T>
中,实现其正常Iterator<T>
阻止等待每个结果请求:
fun <T> ReceiveChannel<T>.asSequence(context: CoroutineContext) =
Sequence {
val iterator = iterator()
object : AbstractIterator<T>() {
override fun computeNext() = runBlocking(context) {
if (!iterator.hasNext())
done() else
setNext(iterator.next())
}
}
}
val resultSequence = resultChannel.asSequence(CommonPool)
答案 1 :(得分:0)
我遇到了同样的问题,最后我想出了一个非常不寻常/复杂的解决方案:
fun Channel<T>.asSequence() : Sequence<T> {
val itr = this.iterator()
return sequence<Int> {
while ( runBlocking {itr.hasNext()} ) yield( runBlocking<T> { itr.next() } )
}
}
我认为这不是特别有效(与@hotkey提供的功能一起使用),但至少对我有一定吸引力。