Kotlin Coroutine 시리즈 1- 비동기 프로그래밍

Jinho Shin·2021년 9월 10일
0

Kotlin Coroutines

목록 보기
1/1

시리즈 1편입니다.

프로젝트에도 자주 사용하고, 세상 편리하다고 느끼는 Kotlin Coroutines에 대해서 한번 이야기를 해보려고 합니다.

Coroutine에 대해 간단히 설명하려고 했는데 하다 보니 글이 길어져 몇 번에 나눠 설명해보도록 하겠습니다.

비동기 프로그래밍

저의 실생활을 예로 들어 설명을 한번 해보겠습니다.
저는 원룸에 살고 있습니다. 그래서 집안일은 모두 제가 담당해야 합니다.
저는 1,2주에 한번 청소를 하는데 청소를 할 때 하는 작업과 순서를 다음과 같다고 가정하겠습니다.
1. 로봇 청소기 돌리기(바닥 쓸기)
2. 바닥 닦기
3. 빨래 돌리기
4. 화장실 청소
5. 설거지

총 5개의 작업을 한다고 할 때 만약에 아무 생각 없이 한다고 하면, 1번에서 5번까지 차례차례로 진행 할 것입니다.

만약에, 각 청소에 걸리는 시간이 1시간이라고 한다면 저는 청소를 다하는 데 총 5시간이 걸립니다. 청소를 많이 하는 분들은 알고 계실 겁니다. 순번대로 할 필요가 없다는 것을요.

시간을 줄일 수 있는 방법이 있을까요?

시간을 줄일 수 있는 방법은 다양하게 있을 수가 있겠지만 머릿속에 생각나는 대로 적어본다면

1. 로봇 청소기 돌리기,   
2. `로봇 청소기가 돌아가는 동안` 설거지하기
3. `로봇 청소기가 돌아가는 동안` 빨래 돌리기
4. 로봇 청소기가 청소를 다하면 바닥 닦기
5. 바닥 닦고 화장실 청소 시작
6. 빨래가 다 끝나면 널고 다시 화장실 청소 마무리

대충 이런 식으로 정리가 될 수 있을 텐데 이것이 사실은 비동기 프로그램의 전부입니다.

디테일

프로그래밍과 연관 지어 조금만 더 깊게 가보겠습니다.
여기서 청소를 하는 주체는 이고 이는 하나의 스레드에 비유할 수 있습니다.
초기에 머릿속에 떠오른 청소, 순번코드로 비유됩니다.

그럼 나(스레드)는 주어진 순번에 따른 청소(코드)는 순차적으로 하나씩 실행하게 됩니다.

그러나 청소를 많이 해본 사람은 굳이 저 순번대로 따를 필요가 없다는 걸 알고 있고, 청소기가 돌아가는 중에 빨래와 설거지를 하는, 즉 비동기적인 방법이 존재한다는 걸 알고 있습니다.

비동기 프로그래밍 기법은 많은 프로그래밍 언어들에게서 나타나는데 대표적인 케이스를 한번 살펴보겠습니다.

비동기 프로그래밍의 종류

Thread

거의 대부분의 언어에서 발견할 수 있을 거 같습니다. 안드로이드에서는 몇 년 전까지만 해도 네트워크 요청과 Local DB를 읽어올 때 새로운 Thread를 만들어 작업을 진행하였습니다.

이 방법은 몇 가지 단점이 존재하는데

1. Context Switching이 요구되고 이는 무거운 작업일뿐더러,
2. 그리고 Thread의 수는 유한합니다.
3. 그리고 자바스크립트는 단일 스레드로 사용도 불가능합니다.

Callbacks

아마 많은 개발자분들이 콜백을 자주 사용하실 거 같은데 콜백도 비동기 프로그램의 일종입니다.
예를 들어 네크워크 요청 함수를 호출하면서 값이 나왔을 때 진행할 함수를 Parameter로 전달하면서 비동기 프로그래밍을 구현합니다.

Callback Hell(콜백 지옥)
함수의 인자 값에 다른 함수를 전달하는 방법도 그 길이가 짧다면 가독성이 문제가 없겠습니다.
하지만 만약 함수가 함수를 부르고, 그 함수가 또 다른 함수를 부르고, 그 함수가 또 다른 함수를 부른다면 가독성이 떨어지고 이해하기가 힘듭니다. 이를 callback hell, 콜백 지옥이라고 부릅니다.

제가 전에 튜토리얼 보면서 자바스크립트를 배워본 적이 있는데 콜백 함수가 주렁주렁 달리는 걸 보고 놀란 기억이 납니다. 그리고 에러 처리는 어떻게 해야 하나? 에 대한 생각도 한적이 있습니다.

Future, Promises and others

제가 한 번도 다뤄보지는 않은 부분이지만 감히 유추를 해본다면, Future, Promises, 미래와 약속을 뜻하는 단어인데 아마 어떤 요청에 대한 값을 미래에 준다는 약속? 을 의미하는거 같습니다.

Kotlin 공식 문서에 이에 대해 짧게 언급하는데, 번역해보자면

"Future와 Promises의 기본 개념은 우리가 함수를 호출 할 때, 어느 시점에 이 함수는 우리에게 추가 작업을 할 수 있는 Promise라는 객체를 리턴한다는 약속한다" 입니다.

fun postItem(item: Item) {
    preparePostAsync()
        .thenCompose { token ->
            submitPostAsync(token, item)
        }
        .thenAccept { post ->
            processPost(post)
        }

}

fun preparePostAsync(): Promise<Token> {
    // makes request and returns a promise that is completed later
    return promise
}

Kotlin 공식 문서에서 가져온 code snippet입니다.
적용해 본 적이 없어서 더 이상 설명하기는 무리일 것 같습니다.
하지만thenCompose, thenAccept, Promise를 보니 뭔가 다른 비동기 프로그래밍 방식이랑 많이 다른 것 같고 초기에 배울게 많은 것처럼 보입니다.

Reactive

흔히 줄여서 Rx라고 부르는 걸로 알고있습니다. Android 자료를 검색하다가도 보이고, 취직 준비를 하고 있는 지금도 거의 기본값으로 Rx에 대한 이해를 요구하는 것 같습니다.

관찰 가능한 stream, 즉 데이터를 관찰이 가능한 하나의 스트림으로 보고 접근을 하는 개념으로 알고 있는데 기본적으로는 Observable Pattern을 사용한다고 합니다.

나중에 한번 Coroutine과 Rx에 대해 비교를 해봐야 할 거 같습니다.

듣기로는 RxJava는 러닝 커브가 초반에 상당하다고 들었고, 코드를 여러번 보기는 했는데 봤을 때 느낀 점은 상당하겠다, 그리고 체이닝이 꽤 많다고 느끼긴했습니다.

다음 편부터 본격적으로 Coroutine에 대해 다뤄보겠습니다.

profile
I will be the King of

0개의 댓글