본문 바로가기
프로그래밍/Flutter

[Flutter] Dart, async / await 비동기 처리

by 신나요 2022. 5. 9.

플러터 앱에서 async와 await를 사용해 비동기 처리 코드를 깔끔하게 유지할 수 있습니다.

 

이번 포스트는 다음 내용을 다루고 있습니다.

  • Future와 then을 사용하는 비동기 처리
  • async와 await 키워드
  • async, await를 사용하는 비동기 처리
  • await와 block의 차이 이해하기

Future와 then을 사용하는 비동기 처리

아래 Future와 then을 사용한 비동기 처리 코드가 있습니다. (Future와 아래 코드에 대한 설명은 이쪽을 참고해 주세요.)

main 함수에서 세 개의 함수를 호출하고 있습니다. mockFileIO가 호출되고 처리가 끝나면 다음 mockHttpRequest를 호출하게 됩니다. mockHttpRequest는 비동기 처리로 즉시 Future를 반환하게 되고 response 변수에 할당을 해주고 있습니다. 프로그램은 block이 되지 않고 계속해서  mockDBQuery를 호출합니다. response.then에서 설정한 함수가 8초 후 Future가 완료되면 비동기로 호출되고 main 처리는 끝나게 됩니다.

출력 값은 위와 같이 나옵니다.

 

현재 mockHttpRequest는 비동기 함수이고, main함수에서 반환되는 Future의 then을 사용해서  비동기 처리를 해주고 있는데요. 위 코드에서 mockDBQuery가 mockHttpRequest의 결괏값으로 검색을 해야 된다고 가정해 보겠습니다.

mockHttpQequest의 Future값을 mockDBQuery에 제공하는 것은 쉽습니다.

then 함수 안으로 mcokDBQuery를 이동하기만 하면 됩니다. 실행하면 아래와 같이 출력 됩니다.

프로그램을 다시 실행하면 FILE IO가 시작됩니다. 그런 다음 HTTP 리퀘스트가 실행되고 완료되기까지 8초 동안 기다립니다. 그러나 데이터베이스 쿼리는 이제 HTTP 리퀘스트의 결괏값에 따라 달라지기 때문에 디비 쿼리도 8초를 대기해야 하며 이를 피할 방법이 없습니다. 이러한 처리는 코드의 결함은 아니지만 8초가 지난 후 디비 쿼리가 시작되고 디비 쿼리의 처리가 오래 걸리는 처리라면 프로그램이 블록 되는 것을 방지해야 합니다.

 

mockDBQuery도 Future를 반환하도록 수정해 보겠습니다.

mockDBQuery를 Future를 반환하도록 수정하였고, response의 then안에서  mockDBquery의 리턴되는 Future의 then을 호출하도록 변경하였습니다. 이제 mockDBQuery를 호출할 때 프로그램을 차단하지 않게 되었지만 코드는 조금 복잡해진 것 같습니다. 드디어 async와 awiat를 이야기할 때가 된 것 같습니다.


async와 await 키워드

비동기 코드를 단순화하기 위해 Dart는 async 및 awiat 키워드를 제공하고 있습니다. async와 await를 사용하면 모든 중첩된 then 호출이 필요하지 않게 되므로 코드를 더 쉽게 읽을 수 있습니다. 마치 동기식 코드와 같이 보여서 깔끔하고 비동기 처리가 되므로 플러터 앱에서 유저 인터페이스를 차단하지 않고 백그라운드로 비동기 코드가 실행됩니다.

async와 awiat로 쓰기 위해서 몇 가지 변경 사항이 있습니다.

 

첫째로 모든 비동기 함수는 async로 표시되어야 합니다. 그런 다음 호출 코드에서 함수 호출 앞에 awiat를 붙입니다.

await는 함수의 결과를 기다립니다. 그러나 반환 값은 Future가 아니고 위 예제의 경우 문자열이 됩니다. async 함수를 await 하는 모든 함수는 async로 표시되어야 합니다. 이제 예제에서 mockHttpRequest와 mockDBQuery를 모두 async, await로 바꿔보겠습니다.

 

async, await를 사용하는 비동기 처리

then의 중첩이 없어지므로 코드가 훨씬 간단하고 읽기 쉬워진 걸 확인해 볼 수 있습니다. 한 가지 분명히 이해할 것은 await는 block 아니라는 점입니다.


await와 block의 차이 이해하기

await는 block과 동일하지 않습니다. 프로그램을 block 하면 모든 것이 중지됩니다. 전체 앱은 block 작업이 완료될 때까지 기다리게 됩니다. 그러나 await는 비동기 함수가 완료될 때까지 함수에 종속된 작업만 일시 중지됩니다. 플러터 앱의 UI 조작이나 다른 부분은 계속 진행할 수 있다는 의미입니다. 플러터 앱에서 block을 시켜 작업을 시킨다면 처리가 끝날 때까지 앱이 완전치 멈춰버리는 사태가 발생하게 됩니다. 이것이 플러터 앱에 HTTP 요청은 반드시 비동기 처리로 해줘야 하는 이유입니다.


 

여기까지 수고하셨습니다. 다음 포스트에서는 비동기 처리에서 발생하는 에러를 핸들링하는 방법에 대해 공부해 보도록 하겠습니다.

댓글