[Android A..Z] Asynchronous 비동기란?

2021. 11. 22. 19:44개발/[Kotlin] 안드로이드 개발

반응형

동기?비동기?

사실 비동기를 알기 전에 동기의 개념붙 알아야 한다. 프로그래밍에서의 동기란, 한 번에 하나의 작업만 진행하는 것을 의미한다. 프로그램이 지금부터 수행해야 할 여러 개의 작업이 있다고 치자.

동기적 작업 방식은 한 직업이 끝나기 전까지 다른 작업을 할 수 없다. 위 그림의 1번 작업이 끝나고 나서야 2번 작업을 시작할 수 있다. 

Ex) 점원이 1명인 카페가 있다. 이 때 손님 세 명이 아서 주문을 한다. 만약 점원이 동기적 방식으로 일한다면, 하나의 주문을 받았을 때 음료수를 만들기 시작해서, 완성 후 손님에게 전달하기 전까지는 다른 주문을 받을 수 없다. 안타깝게도 첫 주문자가 되지 못한 두명의 손님은 카운터에서 계속 기다려야한다.

 

그러나 점원이 비동기적으로 작업을 했다면 상황은 달라질 것이다. 먼저 손님 세 명의 주문을 받고, 동시에 음료수를 만들기 시작해서 먼저 완성된 음료수부터 차례로 전달할 것이다. 음료수를 만들며 겹치는 작업들을 한꺼번에 하게 되니 시간이 절약된다.

이제 프로그래밍에 대입해보자

Asynchronous

비동기식 처리 모델은 병렬적으로 작업을 수행 한다. 즉 작업이 종료되지 않은 상태라 하더라도 대기하지 않고 다음 태스크를 실행한다.

서버에서 데이터를 가져와서 화면에 표시한다고 해보자. 이 과정에서 서버 통신을 하는데 시간이 걸리기 때문에 데이터가 온전히 받아지지 않은 상태에서 화면에 표시하려고 한다면 아마 에러가 나거나 표시되지 않을 것이다. 

그렇기 때문에 동기적으로 다 완료된 후에 다음 코드가 작동해야 하지 않을까? 라는 생각을 했었다.

하지만 정답은 NO였다. 만약 데이터가 다불러와진 다음에 다음 코드들이 진행 된다면 초기화에 많은 시간이 걸릴 것이다. 앱이 커질수록 더 심해진다. 그렇기 때문에 비동기적으로 데이터가 불러진 후에 해야하는 작업같은 경우에는 데이터 작업이 완료된 후에 작업해야한다. 

Ex)
   viewModel.callRooms(input).observe(viewLifecycleOwner, Observer { resource ->
            Log.d(TAG, resource.data.toString())
            when (resource.status) {
                Resource.Status.SUCCESS -> {
                    roomsData = resource.data!!
                    setRecyclerView() // roomsData가 필요하기 때문에 작업이 완료된 후에 리사이클러뷰 작업 실행
                    dialog.dismiss()
                }
                Resource.Status.ERROR -> {
                    toast(requireContext(), resource.message + "\n" + resources.getString(R.string.connect_fail))
                    dialog.dismiss()
                }
                Resource.Status.LOADING -> {
                    dialog.show()
                }
            }
        })
// 코루틴으로 비동기 작업 예시
fun callRooms(data: HashMap<String, Any>) = liveData {
        emit(Resource.loading(null))
        try {
            emit(Resource.success(mainRepository.rooms(data).body()))
        }
        catch(e: Exception) {
            emit(Resource.error(null, e.message ?: "Error Occurred!"))
        }
    }

이와 같이 언제 작업이 끝날지 모르는 작업은 Coroutine을 사용해서 동기, 비동기를 유연하게 잘 구현해야한다.

 

동기 VS 비동기

동기 : 속도가 느림, 진행방향이 일방향이기 대문에 코드에서 에러가 나면 어디인지 파악하기 쉬움

비동기 : 속도가 동기에 비해 빠름

반응형