[Dart] async, await, 동기, 비동기

Ss·2024년 4월 11일
post-thumbnail

astnc, await를 사용해보면서 동기,비동기를 생각해보면 제대로된 개념이 잡혀있지 않아 햇갈리던적이 몇번이 있었다. 개념을 제대로 잡는다는 마음으로 이 글을 작성을 했다.

공식문서

비동기가 필요한 이유

개발을 하다보면 어떤 연산을 기다려야 하는 때가 있다.

  • 네트워크로 데이터 가져오기
  • 데이터베이스에 쓰기
  • 파일에서 데이터 읽기


Future

비동기 결과를 나타내며 완료(값 or 에러), 미완료 상태를 갖고있다.


async/await

비동기 함수를 정의하려면 함수 본문 앞에 async를 추가한다.
await 키워드는 비동기 함수에서만 작동한다.

async를 썼다고 await를 무조건 써야하는건 아니지만 await를 쓰기 위해서는 async가 필요하다. 또한 await는 비동기 함수의 "완성된 결과"를 가져온다.

쉽게 말해 await 키워드를 붙이면 future상태가 완료된 값을 가져온다 라고 생각하면 된다.



코드

시작과 종료사이에 숫자를 세는 코드를 작성을 했다.

아래 코드는 어떠한 대기 없이 순차적으로 실행되는 코드이다.

void main() {
  print("시작");
  count();
  print("종료");
}

void count()  {
    print("하나!");
}


--출력--
시작
하나!
종료

만약 여기서 하나라는 출력이 1초뒤 나오고 싶다면 1초의 딜레이를 주면 된다.

void main() {
  print("시작");
  count();
  print("종료");
}

void count()  {
  Future.delayed(Duration(seconds:1),(){
    print("하나!");    
  });
}

--출력--
시작
종료
(1초 후)
하나!

1초 후 출력은 되었으니 종료가 먼저 출력이 되었다. 이때 사용하는 키워드는 async/await이다.

void main() {
  print("시작");
  count();
  print("종료");
}

void count() async {
  await Future.delayed(Duration(seconds: 1), () {
    print("하나!");
  });
}


--출력--
시작
종료
(1초 후)
하나!

1초 후의 출력을 위해 await를 붙였고 await를 위해 async까지 함께 작성했지만 결과는 이전과 같았다.
이유는 main에서의 count함수 선언에 await 가 붙어있지 않아서이다.
await 키워드가 붙으면 future의 완성된 값을 가져올때까지 대기를 하기 때문에 await가 붙어 있지 않은 main 함수의 count 함수 호출 부분에서 대기 없이 시작과 종료를 한번에 출력을 했기 때문이다.

void main() async {
  print("시작");
  await count();
  print("종료");
}

Future<void> count() async {
  await Future.delayed(Duration(seconds: 1), () {
    print("하나!");
  });
}

--출력--
시작
(1초 후)
하나!
종료

따라서 위와 같이 작성을 한다면 원하는 결과 값을 얻을 수 있다.

번외

await가 future의 완성된 값이라는게 어떤것일까 위의 void 예시 코드로는 적절하지 않아 코드를 수정 해보았다.

void main()  {
  print("시작");
  print(count());
  print("종료");
}

Future<String> count()  {
  return Future.delayed(Duration(seconds: 1), ()=>"하나");
}


--출력--
시작
Instance of '_Future<String>'
종료

위의 코드는 count에서 1초뒤 하나 라는 문자열을 건내주고 main에서는 await 없이 print문으로 출력을 한다.
await가 기다린다는 future의 완성된 값이라는것은 Future에서의 String값을 의미한다. 따라서 await를 붙이지 않는 순간 어떠한 리턴이든 다 받는다는 의미가 되고 1초가 지나 하나 라는 완성된 값이 아닌 Future을 반환하며 시간 또한 1초가 아닌 바로 출력이 된다.

0개의 댓글