(Topic) 003. 코루틴 & 플로우 스터디 복기 2
코루틴 & 플로우 스터디 복기 2
스터디 복기 1에서 다루었던 예제를 Channel을 적용하여 변경해보자.
1. gps로 지도 상 나의 위치를 실시간으로 트래킹하는 앱을 구현한다고 가정하자. 다음의 세부조건을 고려할 떄 어떤식으로 Flow를 사용하면 좋을지 생각해보자.
- 세부 조건
- gps를 통해 위도,경도 좌표값을 1초에 수십회 얻을 수 있다.
- 특정 좌표에 맞춰 지도를 렌더링하는데는 1초미만의 시간이 소요된다.
- 가끔 gps에 노이즈로 인해 전혀 유효하지 않은 좌표가 반환되는데 이 때 이 값을 사용하지 않아야 한다.(예를 들어 이전 좌표가 서울이였는데 그 다음 값이 뉴욕인 경우)
일단 먼저 채널 적용.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| import kotlinx.coroutines.* import kotlinx.coroutines.channels.*
fun getLocation(): Location = LocationManagver.location
fun CoroutineScope.updateLocation() = produce<Location> { while (true) { delay(1000L) send(getLocation()) } }
fun Location.isKorea() = (this.longitude + this.latitude) in 157 .. 175
fun renderingMap(location: Location) { }
fun main() = runBlocking<Unit> { var currentLocation: Location = getLocation() val locations = updateLocation()
while (true) { val location = locations.receive() if (location.isKorea()) { currentLocation = location } renderingMap(currentLocation) }
}
|
버퍼 오버플로우를 응용해본다면 아래와 같이 처리하면 되지 않을까?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| import kotlinx.coroutines.* import kotlinx.coroutines.channels.*
fun getLocation(): Location = LocationManagver.location
fun Location.isKorea() = (this.longitude + this.latitude) in 157 .. 175
fun renderingMap(location: Location) { }
fun main() = runBlocking<Unit> { val channel = Channel<Location>(1, BufferOverflow.DROP_OLDEST) launch { while (true) { send(getLocation()) } }
var currentLocation: Location = getLocation() for (location in channel) { delay(1000L) if (location.isKorea()) { renderingMap(location) } } }
|