// Простой пример Future
Future<String> fetchUserName(int userId) {
return Future.delayed(Duration(seconds: 2), () {
// Имитация задержки сети
if (userId == 1) {
return 'Алексей Петров';
} else {
throw Exception('Пользователь не найден');
}
});
}
// Использование
void main() {
print('Начало запроса...');
fetchUserName(1).then((name) {
print('Получено имя: $name');
}).catchError((error) {
print('Ошибка: $error');
});
print('Запрос отправлен, ожидаем ответ...');
} // Тот же пример с использованием async/await
Future<void> main() async {
print('Начало запроса...');
try {
final userName = await fetchUserName(1);
print('Получено имя: $userName');
} catch (error) {
print('Ошибка: $error');
}
print('Запрос завершен');
} // Пример создания простого Stream
Stream<int> countStream(int max) async* {
for (int i = 1; i <= max; i++) {
await Future.delayed(Duration(seconds: 1));
yield i; // Отправляем значение в поток
}
}
// Использование
void main() {
final stream = countStream(5);
stream.listen(
(value) => print('Получено: $value'),
onError: (error) => print('Ошибка: $error'),
onDone: () => print('Поток завершен'),
);
print('Подписка оформлена, ожидаем события...');
} import 'package:flutter/foundation.dart';
// Функция, которая будет выполняться в отдельном изоляте
int _heavyComputation(int number) {
// Имитация тяжелого вычисления
int result = 0;
for (int i = 0; i < number * 1000000; i++) {
result += i % 100;
}
return result;
}
class HeavyComputationScreen extends StatefulWidget {
@override
_HeavyComputationScreenState createState() => _HeavyComputationScreenState();
}
class _HeavyComputationScreenState extends State<HeavyComputationScreen> {
int _result = 0;
bool _isCalculating = false;
Future<void> _startComputation() async {
setState(() => _isCalculating = true);
// Используем compute для запуска в отдельном изоляте
final result = await compute(_heavyComputation, 1000);
setState(() {
_result = result;
_isCalculating = false;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Тяжелые вычисления')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_isCalculating) CircularProgressIndicator(),
SizedBox(height: 20),
Text('Результат: $_result', style: TextStyle(fontSize: 20)),
SizedBox(height: 20),
ElevatedButton(
onPressed: _isCalculating ? null : _startComputation,
child: Text('Запустить вычисление'),
),
],
),
),
);
}
} import 'dart:isolate';
import 'dart:async';
class BackgroundService {
late SendPort _sendPort;
late Isolate _isolate;
final ReceivePort _receivePort = ReceivePort();
final StreamController<String> _messageController = StreamController.broadcast();
Stream<String> get messages => _messageController.stream;
Future<void> start() async {
// Создаем изолят
_isolate = await Isolate.spawn(
_isolateEntry,
_receivePort.sendPort,
);
// Слушаем сообщения от изолята
_receivePort.listen((message) {
if (message is SendPort) {
_sendPort = message; // Получаем порт для отправки сообщений в изолят
} else if (message is String) {
_messageController.add(message); // Передаем сообщение в UI
}
});
}
void sendCommand(String command) {
_sendPort.send(command);
}
Future<void> stop() async {
_receivePort.close();
_messageController.close();
_isolate.kill(priority: Isolate.immediate);
}
// Эта функция выполняется в отдельном изоляте
static void _isolateEntry(SendPort mainSendPort) {
final ReceivePort isolateReceivePort = ReceivePort();
mainSendPort.send(isolateReceivePort.sendPort);
isolateReceivePort.listen((message) {
if (message == 'START_TASK') {
// Имитация долгой задачи
for (int i = 0; i < 10; i++) {
mainSendPort.send('Прогресс: ${(i + 1) * 10}%');
// Имитация работы
final start = DateTime.now().millisecondsSinceEpoch;
while (DateTime.now().millisecondsSinceEpoch - start < 1000) {
// Ждем 1 секунду
}
}
mainSendPort.send('Задача завершена!');
}
});
}
}
// Использование в Flutter
class IsolateExampleScreen extends StatefulWidget {
@override
_IsolateExampleScreenState createState() => _IsolateExampleScreenState();
}
class _IsolateExampleScreenState extends State<IsolateExampleScreen> {
final BackgroundService _service = BackgroundService();
List<String> _messages = [];
bool _isRunning = false;
@override
void initState() {
super.initState();
_initService();
}
Future<void> _initService() async {
await _service.start();
_service.messages.listen((message) {
setState(() => _messages = [..._messages, message]);
});
}
@override
void dispose() {
_service.stop();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Фоновый сервис')),
body: Column(
children: [
ElevatedButton(
onPressed: _isRunning
? null
: () {
setState(() {
_isRunning = true;
_messages = [];
});
_service.sendCommand('START_TASK');
},
child: Text('Запустить фоновую задачу'),
),
Expanded(
child: ListView.builder(
itemCount: _messages.length,
itemBuilder: (context, index) => ListTile(
title: Text(_messages[index]),
),
),
),
],
),
);
}
} import 'package:flutter/material.dart';
import 'dart:convert';
import 'package:http/http.dart' as http;
class UserListScreen extends StatefulWidget {
@override
_UserListScreenState createState() => _UserListScreenState();
}
class _UserListScreenState extends State<UserListScreen> {
List<User> _users = [];
bool _isLoading = true;
String _errorMessage = '';
@override
void initState() {
super.initState();
_loadUsers();
}
Future<void> _loadUsers() async {
try {
setState(() {
_isLoading = true;
_errorMessage = '';
});
final response = await http.get(
Uri.parse('https://jsonplaceholder.typicode.com/users'),
);
if (response.statusCode == 200) {
final List<dynamic> data = json.decode(response.body);
setState(() {
_users = data.map((json) => User.fromJson(json)).toList();
_isLoading = false;
});
} else {
throw Exception('Ошибка загрузки: ${response.statusCode}');
}
} catch (error) {
setState(() {
_errorMessage = error.toString();
_isLoading = false;
});
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Список пользователей')),
body: _isLoading
? Center(child: CircularProgressIndicator())
: _errorMessage.isNotEmpty
? Center(child: Text('Ошибка: $_errorMessage'))
: ListView.builder(
itemCount: _users.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(_users[index].name),
subtitle: Text(_users[index].email),
);
},
),
floatingActionButton: FloatingActionButton(
onPressed: _loadUsers,
child: Icon(Icons.refresh),
),
);
}
}
class User {
final String name;
final String email;
User({required this.name, required this.email});
factory User.fromJson(Map<String, dynamic> json) {
return User(
name: json['name'],
email: json['email'],
);
}
} import 'dart:ui' as ui;
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'dart:typed_data';
class ImageProcessingScreen extends StatefulWidget {
@override
_ImageProcessingScreenState createState() => _ImageProcessingScreenState();
}
class _ImageProcessingScreenState extends State<ImageProcessingScreen> {
ui.Image? _processedImage;
bool _isProcessing = false;
Future<void> _processImage() async {
setState(() => _isProcessing = true);
// Загружаем тестовое изображение
final ByteData data = await rootBundle.load('assets/sample.jpg');
final Uint8List bytes = data.buffer.asUint8List();
// Обрабатываем в отдельном изоляте
final processedBytes = await compute(_applySepiaFilter, bytes);
// Создаем изображение из обработанных байтов
final codec = await ui.instantiateImageCodec(processedBytes);
final frame = await codec.getNextFrame();
setState(() {
_processedImage = frame.image;
_isProcessing = false;
});
}
// Функция, которая выполняется в изоляте
static Uint8List _applySepiaFilter(Uint8List imageBytes) {
// Простой фильтр сепии (упрощенный пример)
final bytes = List<int>.from(imageBytes);
for (int i = 0; i < bytes.length; i += 4) {
final r = bytes[i];
final g = bytes[i + 1];
final b = bytes[i + 2];
// Применяем эффект сепии
bytes[i] = ((r * 0.393) + (g * 0.769) + (b * 0.189)).clamp(0, 255).toInt();
bytes[i + 1] = ((r * 0.349) + (g * 0.686) + (b * 0.168)).clamp(0, 255).toInt();
bytes[i + 2] = ((r * 0.272) + (g * 0.534) + (b * 0.131)).clamp(0, 255).toInt();
}
return Uint8List.fromList(bytes);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Обработка изображений')),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (_processedImage != null)
RawImage(image: _processedImage!),
SizedBox(height: 20),
if (_isProcessing) ...[
CircularProgressIndicator(),
SizedBox(height: 10),
Text('Обработка изображения...'),
],
ElevatedButton(
onPressed: _isProcessing ? null : _processImage,
child: Text('Обработать изображение'),
),
],
),
),
);
}
} Future<void> loadUserData(int userId) async {
// Параллельное выполнение независимых запросов
final future1 = fetchUserProfile(userId);
final future2 = fetchUserOrders(userId);
final future3 = fetchUserSettings(userId);
// Ожидаем завершения всех Future
final results = await Future.wait([
future1,
future2,
future3,
], eagerError: true); // Прерываем при первой ошибке
print('Профиль: ${results[0]}');
print('Заказы: ${results[1]}');
print('Настройки: ${results[2]}');
}
// Последовательное выполнение зависимых запросов
Future<void> processOrder(int orderId) async {
try {
final order = await fetchOrder(orderId);
final user = await fetchUser(order.userId);
final payment = await processPayment(order, user);
print('Заказ обработан: $payment');
} catch (error) {
print('Ошибка обработки заказа: $error');
await logError(error);
} finally {
await cleanupResources();
}
} import 'dart:isolate';
import 'dart:async';
class IsolatePool {
final List<Isolate> _isolates = [];
final List<SendPort> _ports = [];
final int _poolSize;
IsolatePool(this._poolSize);
Future<void> initialize() async {
for (int i = 0; i < _poolSize; i++) {
final receivePort = ReceivePort();
final isolate = await Isolate.spawn(
_workerFunction,
receivePort.sendPort,
);
final sendPort = await receivePort.first;
_isolates.add(isolate);
_ports.add(sendPort as SendPort);
}
}
Future<T> execute<T>(Function task, dynamic argument) async {
final completer = Completer<T>();
final responsePort = ReceivePort();
// Выбираем изолят по кругу (простой load balancing)
final sendPort = _ports.first;
sendPort.send({
'task': task,
'argument': argument,
'responsePort': responsePort.sendPort,
});
responsePort.listen((message) {
if (message is T) {
completer.complete(message);
} else if (message is Exception) {
completer.completeError(message);
}
responsePort.close();
});
return completer.future;
}
static void _workerFunction(SendPort mainSendPort) {
final receivePort = ReceivePort();
mainSendPort.send(receivePort.sendPort);
receivePort.listen((message) {
final task = message['task'] as Function;
final argument = message['argument'];
final responsePort = message['responsePort'] as SendPort;
try {
final result = task(argument);
responsePort.send(result);
} catch (e) {
responsePort.send(Exception(e.toString()));
}
});
}
void dispose() {
for (final isolate in _isolates) {
isolate.kill();
}
}
} // 1. Обработка в async/await
Future<void> loadData() async {
try {
final data = await fetchData();
await processData(data);
} on SocketException catch (e) {
print('Ошибка сети: $e');
showNetworkError();
} on FormatException catch (e) {
print('Ошибка формата данных: $e');
showDataError();
} catch (e) {
print('Неизвестная ошибка: $e');
showGenericError();
}
}
// 2. Обработка в Future
Future<void> loadUserProfile() {
return fetchProfile()
.then((profile) => validateProfile(profile))
.then((validated) => saveProfile(validated))
.catchError((error) {
print('Ошибка загрузки профиля: $error');
return Profile.defaultProfile();
}, test: (error) => error is! CriticalError)
.whenComplete(() => log('Загрузка профиля завершена'));
}
// 3. Обработка в Isolate
Future<T> runInIsolateWithErrorHandling<T>(
Function task,
dynamic argument,
) async {
try {
return await compute(task, argument);
} on IsolateSpawnException catch (e) {
print('Не удалось запустить изолят: $e');
rethrow;
} catch (e) {
print('Ошибка в изоляте: $e');
rethrow;
}
}