인프런 커뮤니티 질문&답변

011414님의 프로필 이미지

작성한 질문수

Flutter 앱 개발 기초

Dart의 비동기 함수에 대한 aysnc, await 질문입니다.

해결된 질문

22.07.15 15:35 작성

·

643

1

Dart에서 비동기로 함수가 동작하려면 async, await 키워드를 사용하는 것으로 알고 있었는데요..
 
강의 자료에서
 
4회차 강의 5:24에 보시면 비동기 관련 소스코드 설명이 동영상과 자료에 있습니다.
---------------------------------------------------------
HTTP 요청은 응답까지 시간이 걸리기 때문에 비동기 코드입니다.
따라서 동기로 작동하려면 아래와 같이 async & await을 추가하면 됩니다.
 
main() async
{
Response result = await Dio().get("URL");
print(result.data);
}
 
----------------------------------------------------------
그런데, 위의 소스가 비동기로 동작하는 소스 같은데, "동기로 동작하려면" 이라고 되어 있어서요.
오타인지? 아니면 제가 잘 모르는 부분이 있는건지 설명 부탁드립니다.

답변 2

1

011414님의 프로필 이미지
011414
질문자

2022. 07. 15. 20:11

네,,, 100%는 아니지만 어느 정도는 이해한 거 같습니다.

하지만 Dart에 아직 많이 이해도가 높지 않아, 파일처리 / HTTP 통신이 기본적으로 비동기로 동작한다는 말이 아직은 잘 이해가 가지 않기는 합니다.

내부 구현 소스를 보면 이해가 갈거 같기는 한데, 점점 더 익숙해 져 가고 있습니다.

친절한 답변 감사드립니다. ^^

1

DevStory님의 프로필 이미지
DevStory
지식공유자

2022. 07. 15. 18:43

안녕하세요 011414님

HTTP 요청, File 읽기/쓰기, DataBase 연결 등과 같이 동작하는데 시간이 걸리는 코드들은 기본적으로 비동기로 작동하게 됩니다. 즉, 실행한 코드의 결과가 넘어오기 전에 다음 코드가 실행된다고 보시면 됩니다.

예를들어 HTTP 요청을 통해 가져온 데이터를 보여주는 로직이 있다고 가정해 보겠습니다.

HTTP 요청은 기본적으로 비동기로 작동하기 때문에, HTTP 요청을 하고 응답을 받기 전에 다음 로직이 실행될 것입니다.  하지만 아직 응답을 받지 않았기 때문에 Dart에선 미래를 의미하는 Future가 출력되고, 여기엔 HTTP 응답 내용이 들어있지 않습니다.

위 문제를 해결하기 위해선, HTTP 요청 후 응답을 받을 때까지 기다린 뒤 다음 로직을 실행하는 것 입니다.
위 해결 방법을 구현하는 여러 방법이 있는데 그 중 하나가 async & await 입니다.

위 이미지와 같이 비동기로 작동하는 코드 앞에 await을 붙여주게 되면, 해당 코드는 동기적으로 작동하게 됩니다. 즉, 이제 fetch 함수 내부는 모두 동기적으로 작동한다고 볼 수 있습니다. 그런데 함수 내부에 await을 사용하는 경우, 해당 함수는 시간이 걸리는 코드를 기다리기 때문에 함수 자체가 시간이 걸리는 함수가 되었다고 볼 수 있습니다. 앞서 말씀드렸다시피 Dart에서 시간이 걸리는 코드를 기본적으로 비동기로 다루게 되어 있습니다. 따라서 fetch 함수에 async를 붙여 해당 함수는 시간이 걸리는 비동기 함수라고 표시해줘야 합니다. 그래서 await을 쓰려면 해당 함수에 async를 붙이도록 dart에선 강제화 되어 있다고 이해하실 수 있습니다.

정리하면 fetch 함수의 내부 로직은 await이 붙어 있기 때문에 동기적으로 작동하게 되고, await으로 인해 fetch 함수 자체는 시간이 걸리는 함수가 되어 async를 붙여 비동기 함수임을 표시합니다.

따라서 아래와 같은 코드가 있을 때 fetch는 비동기 함수이므로 1, 2, 결과가 출력 되게 됩니다. main 함수 내부에서 fetch()는 비동기로 작동하지만, fetch 함수 내부에선 동기적으로 로직이 진행됩니다.



fetch 함수 앞에 await을 붙여 동기적으로 작동하게 만든다면 결과가 1 / 결과 / 2로 출력되게 되며, main 함수 내부에서 await을 사용했기 때문에 main 함수에는 async를 붙여 비동기 함수로 선언해 주어야 합니다.

DartPad에서 위 내용을 예제로 만들어 두었으니 참고해 주세요.
- DartPad async & await 예제1
- DartPad async & await 예제2
- DartPad async & await 예제3


위 내용을 바탕으로 질문 주신 "동기로 작동하려면"이라는 부분에 답변 드리자면, 비동기 함수를 await 없이 실행하는 경우, 해당 비동기 함수 다음 줄이 바로 실행되는 흐름과, 비동기 함수 내부 흐름 두 개로 나뉘게 됩니다. 언급하신 "소스가 비동기로 동작하는 소스 같은데" 부분은 전자에 해당한다고 보실 수 있고, "동기로 작동하려면" 부분은 함수 내부에 await을 붙여서 함수 내부 흐름을 동기로 만드는 부분에 해당한다고 이해하실 수 있습니다.

답변에 모호한 부분이 있으시면 질문 남겨 주세요.
감사합니다.❤️

 

 

011414님의 프로필 이미지

작성한 질문수

질문하기