[Flutter] 동기와 비동기(feat.Futures, await, async)

공부할거야·2022년 9월 26일
0

flutter

목록 보기
1/5

동기와 비동기

동기: 모든 동작을 차례대로 수행하는 것으로 요청한 자리에서 결과가 주어져야 한다.
비동기: 어떤 동작이 완료 되지 않아도 다음 동작을 수행하는 것으로 요청에 따른 응답을 즉시 처리하지 않아도 대기시간 동안 다른 요청을 처리 가능한 방식이다.

동기 방식은 직관적이고 간단하지만 결과가 나올 때까지 아무것도 못하고 대기해야 한다.
비동기 방식은 복잡하고 결과가 나올 때까지 동기에 비해 시간이 더 걸리지만 대기시간동안 다른 작업을 할 수 있다. -> 자원을 효율적으로 사용할 수 있다.

콜백 함수

콜백(callback) 함수: 비동기 방식에서 수행이 완료되었을 때 수행해야 할 작업을 래핑한 함수


Flutter에서 비동기 처리

Future

비동기 처리를 위해서 존재
작업이 완료될 경우 요청한 데이터 혹은 에러가 담겨 감싸져 있다

Future<T>

작업이 완료되지 않은 미완성의 경우에는 값을 만들어내기 전의 future가 반환된다.
작업이 완료될 경우 Future가 반환되며 여기에는 작업 성공 시 요청한 데이터 T, 실패 시 에러가 들어있다.(이 Future에서 값을 꺼내는 방법은 아래에 존재)

<예시 - 비동기 처리를 통해 이미지 가져오기>

  getImage(ImageSource imageSource) {

    picker.pickImage(source: imageSource)
        .then((image) => File(image!.path))
        .catchError((error) {print(error);});
  }

then 메소드를 사용해 성공했을 경우 나오는 데이터 T를 처리
catchError 메소드를 사용해 실패했을 때 나오는 에러를 핸들링

async/await

async 함수 안에서만 await 키워드를 사용할 수 있으며 async의 반환값은 Future이다.
async/await은 비동기를 동기처럼 사용할 수 있다.

<예시 - async/await 사용>

 Future getImage(ImageSource imageSource) async {
   final image = await picker.pickImage(source: imageSource);

   setState(() {
     _image = File(image!.path); // 가져온 이미지를 _image에 저장
   });
 }

pickImage는 Future 형식을 반환해준다.
이 반환된 Future 형식을 await을 통해 한 겹 벗겨내어 성공했을 경우 image에 원하는 값을 넣을 수 있다.
실패했을 경우를 위해 try catch로 에러를 핸들링 해줄 수 있다.


Flutter에서 비동기 방식 사용하기

  1. listen 사용 - 일정 주기로 처리 결과를 확인
    아래 코드는 사용자의 위치를 받아오는 코드이다. listen을 통해 일정 시간마다 위치를 가져온다.
    _positionStream.controller.stream.listen((pos) {
      _position = pos;
      _polylineCoordinates
          .add(google_map.LatLng(_position!.latitude, _position!.longitude));

    });
  1. await async 사용 - 동작을 처리할 때까지 대기

    아래 코드를 통해 사용할 마커를 입력한 경로에서 가져온다.
    await을 붙여 getBytesFromAsset 함수가 완료될 때까지 대기한다.

    Future<BitmapDescriptor> getPictuerMarker(String path) async {
      Uint8List makerIconBytes = await getBytesFromAsset(path);
      return BitmapDescriptor.fromBytes(makerIconBytes);
    }
  
  3. notifyListeners 사용 - 비동기 처리 완료 알림
  비동기 처리가 완료되면 처리가 완료되었음을 알려야 한다. 이때 notifyListeners를 사용해 작업 완료를 알리고 이는 UI에 반영된다. 
  
Future<void> getPlaceList() async {
	try {
  		final routeFromJsonFile = await rootBundle.loadString('assets/json/place.json');
  		_sightList = PlaceList.fromJson(routeFromJsonFile).places ?? <Place>[];

        if (_sightList.isEmpty) {
          _state = MarkerListState.empty;
        } else {
          _state = MarkerListState.placeCompleted;
        }
        notifyListeners();
      } catch (e) {
        _state = MarkerListState.empty;
      }	}


*그림 설명 추가하기
profile
아마도?

0개의 댓글