[flutter] flutter 7 (Future)

허성재's avatar
Oct 11, 2024
[flutter] flutter 7 (Future)
 
Flutter에서 Future는 비동기 작업을 처리하기 위한 기본 개념입니다. Future는 나중에 완료될 수 있는 작업을 나타내며, 완료되면 성공적인 결과 또는 오류가 반환됩니다.
notion image
Future<int> getNum() { Future<int> fNum = Future.delayed(Duration(seconds: 1), () => 1); return fNum; } Future start() async { int n = await getNum(); print(n + 10); } void main() async { await start(); print("화면전환"); }
 
import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:homeapp/a_page.dart'; void main() { runApp(ProviderScope(child: MyApp())); } class MyApp extends StatelessWidget { const MyApp({super.key}); @override Widget build(BuildContext context) { return const MaterialApp( debugShowCheckedModeBanner: false, home: APage(), ); } } import 'package:flutter/material.dart'; import 'package:homeapp/home_repository.dart'; class APage extends StatelessWidget { const APage({super.key}); @override Widget build(BuildContext context) { return Scaffold(body: Text("넘버 : ${HomeRepository().fetchNumber()}")); } } // 통신 담당 class HomeRepository { Future<int> fetchNumber() { return Future.delayed(Duration(seconds: 3), () => 3); } int fetchNumberV2() { return 5; } }
 
통신에서 데이터 빌드하는 가장기본
import 'package:flutter/material.dart'; import 'package:homeapp/home_repository.dart'; class FPage extends StatelessWidget { const FPage({super.key}); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar(title: Text("FPage")), body: Column( children: [ Container( color: Colors.yellow, height: 300, ), FutureBuilder( future: HomeRepository().fetchNumber(), builder: (context, snapshot) { if (snapshot.hasData) { return Center( child: Text( "${snapshot.data}", style: TextStyle(fontSize: 30), ), ); } else { return CircularProgressIndicator(); } }, ), ], ), ); } }
 
FutureBuilder를 통해 snapshot을 이용할수 있고 이것은 데이터가 들어왔을때를 캐치해서 데이터를 뿌릴수 있다.
StateNotifierProvider 는 async안된다 창고는 바로 만들어져야 한다.
그것을 대신하는게 FutureProvider 이다 퓨처 창고를 던질수 있다. 전체적으로 봤을때StateNotifierProvider 를 사용하는게 나을거같다.. 창고를 만들어질때까지 기다리는것 보다 null로 만들고 데이터를 갱신하는게 났다고 한다.
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:homeapp/home_repository.dart'; // 뷰 모델 (창고) class HomeVM extends StateNotifier<int?> { HomeVM(super.state); Future<void> notifyInit() async { int num = await HomeRepository().fetchNumber(); // 3초 state = num; } } // 뷰 모델 관리하는 관리자 (창고 관리자) // watch하거나, read할때 실행됨 (View에서 실행시킴) final homeProvider = StateNotifierProvider<HomeVM, int?>((ref) { HomeVM vm = HomeVM(null); vm.notifyInit(); return vm; });
먼저 null 인 vm을 리턴해주고 async걸린 notifyInit이 끝나 state 를 바꾸면
watch가 캐치해서 촥촥촥!
class HomeBody extends ConsumerWidget { @override Widget build(BuildContext context, ref) { int? num = ref.watch(homeProvider); if(num == null){ return Center(child: CircularProgressIndicator()); }else{ return Center( child: Text("숫자 : $num"), ); } } }
Share article

heo-gom