Xabier Gorostidi
09/06/2020, 6:41 PMoverride fun startScan(
timeout: Long
): Flow<Result<List<Devices>>> {
return merge(
devicesData.foundList.map { Result.Success(it) },
flow {
delay(timeout)
emit(Result.Error(Errors.DeviceDiscoveryError))
}
)
.onStart {
// Here device discovery is launched, but it's callback based so withTimeout doesn't fit very well here
}
.map {
logger().d("device received here")
stopScan()
it
}
.catch { e ->
logger().e("Error: $e")
stopScan()
emit(Result.Error(Errors.DeviceDiscoveryError))
}
.flowOn(ioDispatcher)
}
What I want is the first item emitted by either of those two flows may finish the returning one and ignore future ones. For example, in this example, if a device is found, the timeout will also be called there emitting another item. I've tried using withTimeout
and also coroutineContext.cancelChildren()
when an item is received, but I'm getting into a loop when that's captured in the catch
block. What should be the best approach for this problem?