본문 바로가기
컴퓨터 언어/Kotlin

07. 코루틴의 Async and Await

by 가나무마 2022. 7. 6.
728x90

코루틴을 launch로 실행하면 함수가 차례대로 동기적으로 실행됩니다.

그러나 네트워크 작업과 같이 오래 걸리는 작업은 결과를 받기 전에 다른 작업을 실행하고 싶을 때가 있습니다.

이럴 때 우리는 비동기화로 실행을 하는데 코루틴에선 이를 async와 await를 사용하여 구현합니다.

 

[launch를 썼을 때]

package com.goodee.test

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.databinding.DataBindingUtil
import com.goodee.test.databinding.ActivityMainBinding
import kotlinx.coroutines.*

class MainActivity : AppCompatActivity() {
    private val TAG: String = "로그"
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.nextBtn.setOnClickListener {
            Log.d(TAG,"MainActivity - Before :  run blocking ${Thread.currentThread().name}")
            val startTime = System.currentTimeMillis()
            CoroutineScope(Dispatchers.IO).launch {
                // 네트워크 1 요청
                val answer1 = networkCall1()
                Log.d(TAG,"MainActivity - time : ${System.currentTimeMillis() - startTime} network1 is finish $answer1")
                // 네트워크 2 요청
                val answer2 = networkCall2()
                Log.d(TAG,"MainActivity - time : ${System.currentTimeMillis() - startTime} network2 is finish $answer2")
            }
        }
    }

    // 3초의 응답 시간이 필요한 network 함수
    private suspend fun networkCall1(): String {
        delay(3000)
        return "network1"
    }

    // 5초의 응답 시간이 필요한 network 함수
    private suspend fun networkCall2(): String {
        delay(5000)
        return "network2"
    }
}

[출력 결과]

2022-07-06 21:52:10.267 9962-9962/com.goodee.test D/로그: MainActivity - Before :  run blocking main
2022-07-06 21:52:13.276 9962-9994/com.goodee.test D/로그: MainActivity - time : 3009 network1 is finish network1
2022-07-06 21:52:18.279 9962-9994/com.goodee.test D/로그: MainActivity - time : 8011 network2 is finish network2

 

network1의 요청이 끝나야 network2 요청을 하고 결과적으로 8(3 + 5)초의 시간이 걸린다.

 


 

동기적으로 실행 될 필요가 없는 이러한 함수들을 async(비동기)로 실행하면 앞선 네트워크 함수가 종료 되기 이전에 다음 함수를 실행하여 걸리는 시간의 총합을 아낄 수 있습니다.

async로 실행하여 리턴 받은 객체는 deferred이므로 await을 하여 결과를 기다려서 받을 수 있습니다.

package com.goodee.test

import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import androidx.databinding.DataBindingUtil
import com.goodee.test.databinding.ActivityMainBinding
import kotlinx.coroutines.*

class MainActivity : AppCompatActivity() {
    private val TAG: String = "로그"
    private lateinit var binding: ActivityMainBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.activity_main)
        binding.nextBtn.setOnClickListener {
            Log.d(TAG,"MainActivity - Before :  run blocking ${Thread.currentThread().name}")
            val startTime = System.currentTimeMillis()
            CoroutineScope(Dispatchers.IO).launch {
                // 네트워크 1 비동기 요청
                val defer1 = async { networkCall1() }
                // 네트워크 2 비동기 요청
                val defer2 = async { networkCall2() }

                val str1 = defer1.await()
                Log.d(TAG,"MainActivity - time : ${System.currentTimeMillis() - startTime} network1 is finish $str1")
                val str2 = defer2.await()
                Log.d(TAG,"MainActivity - time : ${System.currentTimeMillis() - startTime} network2 is finish $str2")
            }
        }
    }

    // 2초의 응답 시간이 필요한 network 함수
    private suspend fun networkCall1(): String {
        delay(2000)
        return "network1"
    }

    // 3초의 응답 시간이 필요한 network 함수
    private suspend fun networkCall2(): String {
        delay(3000)
        return "network2"
    }
}

[출력 결과]

2022-07-06 22:04:20.547 10616-10642/com.goodee.test D/로그: MainActivity - time : 2008 network1 is finish network1
2022-07-06 22:04:21.546 10616-10642/com.goodee.test D/로그: MainActivity - time : 3008 network2 is finish network2

 

728x90
반응형

'컴퓨터 언어 > Kotlin' 카테고리의 다른 글

코틀린 - const val vs val  (0) 2022.09.30
06. 코루틴의 Job, waiting, Cancelation  (0) 2022.07.05
05. 코루틴의 runBlocking  (0) 2022.07.05
04. 코루틴의 Context  (0) 2022.07.05
03. 코루틴 suspend 함수  (0) 2022.07.05