(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.*

// 1. GPS 좌표를 반환하는 가상의 함수 정의
fun getLocation(): Location = LocationManagver.location

// 2. 1초마다 GPS 좌표를 얻어온다.
fun CoroutineScope.updateLocation() = produce<Location> {
while (true) {
delay(1000L)
send(getLocation())
}
}

// 3. 국내 범위가 아니면 노이즈로 판정한다.
fun Location.isKorea() = (this.longitude + this.latitude) in 157 .. 175

fun renderingMap(location: Location) {
// Redering a map.
}

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.*

// 1. GPS 좌표를 반환하는 가상의 함수 정의
fun getLocation(): Location = LocationManagver.location

// 2. 국내 범위가 아니면 노이즈로 판정한다.
fun Location.isKorea() = (this.longitude + this.latitude) in 157 .. 175

fun renderingMap(location: Location) {
// Redering a map.
}

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)
}
}
}