본문 바로가기

컴퓨터 언어/Kotlin

07. 코루틴의 Async and Await

코루틴을 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