동기와 비동기의 차이
동기
- '직렬적'으로 작동하는 방식
비동기 -
- '병렬적'으로 작동하는 방식이다.
- 비동기란 특정 코드가 끝날때 까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하는 것
Future와 Stream의 차이( FutureBuilder(), StreamBuilder()** )**
FutureBuilder()
- 일회성 데이터에 사용하기 적합 (이미지 가져오기, 파일 가져오기 등)
- 데이터의 캐싱이 가장 큰 장점
- setState가 없이 자동으로 화면에 변화를 FutureBuilder가 적용해줄 수 있다.
- connectionState*가 바뀔때마다 builder함수가 새로 불린다.
- ConnectionState의 상태 4가지
- ConnectionState.none - null 일 때 initialData, defaultValue가 사용된다.
- ConnectionState.active - null 아니지만 값을 받아오진 않았을 때
- ConnectionState.waiting - 데이터가 오고 있으며 곧 결과를 얻을 수 있을 때
- ConnectionState.done - 데이터가 도착하였을 때
- ConnectionState의 상태 4가지
StreamBuilder()
- 수시로 변하는 데이터에 사용하기 적합하다. (지도, 음악 등)
- StreamBuilder 또한 데이터 캐싱이 됨.
- async 가 아닌 async* 를 사용한다.
- return 이 아닌 yield를 사용한다.
FutureBuilder()의 간단 예제
import 'dart:math';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
final textStyle = TextStyle(
fontSize: 16.0,
);
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
// 화면에 나온다 -> connectionState가 바뀔때마다 builder함수가 새로 불린다.
// setState가 없이 자동으로 화면에 변화를 FutureBuilder가 적용해줄 수 있다
// connectionState가 waiting -> done 으로 바뀜을 알 수 있음
child: FutureBuilder(
future: getNumber(),
builder: (context, snapshot) {
if(snapshot.hasData) {
// 데이터가 있을 때 위젯 렌더링
}
if(snapshot.hasError) {
// 에러가 났을 때 위젯 렌더링
}
// 로딩중일때 위젯 렌더링
// 한번도 데이터를 저장하지 않았을 때(not hasData) 로딩바를 보여주는게 좋다.
// if (!snapshot.hasData) {
// return Center(
// child: CircularProgressIndicator(),
// );
// }
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'FutureBuilder',
style: textStyle.copyWith(
fontWeight: FontWeight.w700,
fontSize: 20.0,
),
),
Text(
'ConState:${snapshot.connectionState}',
style: textStyle,
),
Text(
'Data : ${snapshot.data}',
style: textStyle,
),
Text(
'Error : ${snapshot.error}',
style: textStyle,
),
// setState 버튼을 누르면 해당 클래스의 빌더가 다시 실행되면서 Future도 재실행 됨.
// Data가 null이 안들어 가는 이유? -> FutureBuilder의 캐싱 때문(기존 데이터가 유지된 상태에서 재빌드 )
ElevatedButton(
onPressed: () {
setState(() {});
},
child: Text('setState'))
],
);
},
),
));
}
Future<int> getNumber() async {
await Future.delayed(Duration(seconds: 3));
final random = Random();
// 에러를 던지면 data는 null로 돌아가고 error에는 error가 나옴
throw Exception('에러가 발생했습니다.');
return random.nextInt(100);
}
}
FutureBuilder()의 간단 예제
import 'dart:math';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
@override
Widget build(BuildContext context) {
final textStyle = TextStyle(
fontSize: 16.0,
);
return Scaffold(
body: Padding(
padding: const EdgeInsets.all(8.0),
child: StreamBuilder<int>(
stream: streamNumbers(),
builder: (context, AsyncSnapshot<int> snapshot) {
return Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Text(
'StreamBuilder',
style: textStyle.copyWith(
fontWeight: FontWeight.w700,
fontSize: 20.0,
),
),
Text(
'ConState:${snapshot.connectionState}',
style: textStyle,
),
Text(
'Data : ${snapshot.data}',
style: textStyle,
),
Text(
'Error : ${snapshot.error}',
style: textStyle,
),
ElevatedButton(
onPressed: () {
setState(() {});
},
child: Text('setState'))
],
);
},
),
));
}
Future<int> getNumber() async {
await Future.delayed(Duration(seconds: 3));
final random = Random();
return random.nextInt(100);
}
Stream<int> streamNumbers() async* {
for(int i = 0; i < 10; i ++) {
if (i == 5){
throw Exception('i = 5');
}
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
}
'Flutter' 카테고리의 다른 글
[Flutter] TextField 위젯의 textAlignVertical 속성 (TextField 정렬) (0) | 2022.12.28 |
---|---|
[Flutter] 하단바, 페이지 하단에 떠 있는 버튼 위젯(FloatingActionButton) (0) | 2022.12.27 |
[Flutter] Calendar 구현(table_calendar 오픈소스 활용) (0) | 2022.12.26 |
[Flutter] Class와 Widget (0) | 2022.12.22 |
[Flutter] 문법 정리 (0) | 2022.12.22 |