البرمجة غير المتزامنة — أساسيات Flutter
البرمجة غير المتزامنة في Dart
1. Future و async/await
// دالة غير متزامنة
Future<String> fetchData() async {
await Future.delayed(Duration(seconds: 2));
return 'البيانات جاهزة!';
}
// استخدام
void main() async {
print('جاري التحميل...');
String result = await fetchData();
print(result);
}
// أو باستخدام then
fetchData().then((result) {
print(result);
}).catchError((error) {
print('خطأ: $error');
});
2. معالجة الأخطاء
Future<void> loadUser() async {
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final data = jsonDecode(response.body);
print(data);
} else {
throw Exception('فشل التحميل');
}
} catch (e) {
print('خطأ: $e');
} finally {
print('انتهى التحميل');
}
}
3. FutureBuilder
class UserProfile extends StatelessWidget {
Future<Map<String, dynamic>> fetchUser() async {
final response = await http.get(
Uri.parse('https://api.example.com/user/1'),
);
return jsonDecode(response.body);
}
@override
Widget build(BuildContext context) {
return FutureBuilder<Map<String, dynamic>>(
future: fetchUser(),
builder: (context, snapshot) {
// جاري التحميل
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
// خطأ
if (snapshot.hasError) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error, size: 48, color: Colors.red),
Text('حدث خطأ: ${snapshot.error}'),
ElevatedButton(
onPressed: () {}, // إعادة المحاولة
child: Text('إعادة المحاولة'),
),
],
),
);
}
// نجاح
if (snapshot.hasData) {
final user = snapshot.data!;
return Column(
children: [
CircleAvatar(
backgroundImage: NetworkImage(user['avatar']),
),
Text(user['name']),
Text(user['email']),
],
);
}
return Container();
},
);
}
}
4. Stream و StreamBuilder
// إنشاء Stream
Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i;
}
}
// استخدام مع StreamBuilder
class CounterScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return StreamBuilder<int>(
stream: countStream(10),
builder: (context, snapshot) {
if (snapshot.hasData) {
return Text(
'${snapshot.data}',
style: TextStyle(fontSize: 48),
);
}
return CircularProgressIndicator();
},
);
}
}
// StreamController
class ChatService {
final _controller = StreamController<Message>.broadcast();
Stream<Message> get messages => _controller.stream;
void sendMessage(Message msg) {
_controller.add(msg);
}
void dispose() {
_controller.close();
}
}
5. مثال تطبيقي: تحميل قائمة منتجات
class ProductsScreen extends StatefulWidget {
@override
_ProductsScreenState createState() => _ProductsScreenState();
}
class _ProductsScreenState extends State<ProductsScreen> {
late Future<List<Product>> _productsFuture;
@override
void initState() {
super.initState();
_productsFuture = _fetchProducts();
}
Future<List<Product>> _fetchProducts() async {
final response = await http.get(
Uri.parse('https://api.example.com/products'),
);
if (response.statusCode == 200) {
final List<dynamic> data = jsonDecode(response.body);
return data.map((json) => Product.fromJson(json)).toList();
} else {
throw Exception('فشل تحميل المنتجات');
}
}
void _refresh() {
setState(() {
_productsFuture = _fetchProducts();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('المنتجات'),
actions: [
IconButton(
icon: Icon(Icons.refresh),
onPressed: _refresh,
),
],
),
body: FutureBuilder<List<Product>>(
future: _productsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return Center(child: CircularProgressIndicator());
}
if (snapshot.hasError) {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error_outline, size: 48, color: Colors.red),
SizedBox(height: 16),
Text('حدث خطأ في التحميل'),
SizedBox(height: 16),
ElevatedButton(
onPressed: _refresh,
child: Text('إعادة المحاولة'),
),
],
),
);
}
final products = snapshot.data!;
if (products.isEmpty) {
return Center(child: Text('لا توجد منتجات'));
}
return RefreshIndicator(
onRefresh: () async {
_refresh();
},
child: ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
final product = products[index];
return ProductCard(product: product);
},
),
);
},
),
);
}
}
// Model
class Product {
final int id;
final String name;
final double price;
final String image;
Product({
required this.id,
required this.name,
required this.price,
required this.image,
});
factory Product.fromJson(Map<String, dynamic> json) {
return Product(
id: json['id'],
name: json['name'],
price: json['price'].toDouble(),
image: json['image'],
);
}
}
اختبر فهمك