코루틴_스코프와_suspend_함수_호출_문제 - boostcampwm-2024/and04-Nature-Album GitHub Wiki

문제 상황

프로젝트에서 Firestore와 통신하는 createUserInFirestore 함수가 suspend로 선언되어 있었다. 그런데 이 함수를 일반 함수에서 호출하면서 문제가 발생했다.

문제의 원인

  1. createUserInFirestoresuspend 함수이다.
    • suspend 함수란 코루틴 내에서만 실행할 수 있는 함수로, 비동기 작업을 처리하기 위해 설계된다.
  2. 일반 함수에서 suspend 함수를 호출하려고 했고, 이로 인해 **빨간 줄(컴파일 오류)**이 뜨게 되었다.
    • suspend 함수는 코루틴 스코프 안에서 실행되어야 한다.
  3. *UI 스레드(Main Thread)**에서 직접 호출하려다 보니 Firestore와의 통신이 UI를 멈출 가능성도 있었다.

해결해야 할 과제

  • createUserInFirestore와 같은 suspend 함수는 반드시 코루틴 스코프 내에서 실행해야 한다.
  • Firestore와의 통신이 완료될 때까지 기다리는 동안 Main Thread가 멈추지 않도록 비동기적으로 작업을 처리해야 한다.

해결 방안

  1. 코루틴 스코프 생성
    • viewModelScope, lifecycleScope, 또는 GlobalScope를 사용하여 코루틴 스코프를 생성하고 그 안에서 suspend 함수를 호출한다.

    • 예를 들어:

      viewModelScope.launch {
          createUserInFirestore()
      }
      
      
    • 이렇게 하면 Firestore 통신을 비동기적으로 처리하며 UI가 멈추는 것을 방지할 수 있다.

  2. Main Thread와의 분리
    • Firestore와 같은 네트워크 작업은 Main Thread에서 처리할 수 없으므로 코루틴을 통해 별도의 스레드에서 실행되도록 해야 한다.

    • Dispatchers.IO를 사용하여 I/O 작업을 처리할 수 있다:

      viewModelScope.launch(Dispatchers.IO) {
          createUserInFirestore()
      }
      
      

결론

이 문제는 suspend 함수 호출코루틴 스코프의 필요성에 대한 이해 부족에서 발생한 문제였다. 이를 해결하기 위해 다음과 같은 점을 명확히 정리하게 되었다:

  1. suspend 함수 호출 원칙:
    • suspend 함수는 반드시 코루틴 내에서 호출해야 한다.
    • 일반 함수에서 호출하려면 launch, async 같은 코루틴 빌더를 사용해야 한다.
  2. 비동기 작업의 중요성:
    • 네트워크나 데이터베이스 작업은 UI와 분리하여 처리해야 한다.
    • 이를 위해 Dispatchers.IOviewModelScope 같은 코루틴 스코프를 적절히 활용한다.

이 문제를 해결하면서 코루틴과 suspend 함수의 개념이 더 명확해졌고, 앞으로 비슷한 상황에서 적절히 코드를 작성할 수 있는 기반을 마련하게 되었다.