Flutter条件逻辑处理插件either_dart的使用
Flutter条件逻辑处理插件either_dart的使用
介绍
either_dart
是一个用于错误处理和铁路导向编程(Railway Oriented Programming)的库。它支持异步 map
和 then
操作,简化了与异步计算 Future<Either>
的工作。
安装
在 pubspec.yaml
文件中添加依赖:
dependencies:
either_dart: ^latest_version # 替换为最新版本号
文档
使用方法
基本用法
创建自定义错误类型
首先,创建两个实体类来表示可能的错误和成功的结果:
enum AppError {
NotFound,
BadRequest,
ServerError,
BadResponse,
JsonParsing,
}
class MyError {
final AppError key;
final String? message;
const MyError({
required this.key,
this.message,
});
}
使用 Either 类型
可以使用 Either
来返回成功或失败的结果:
Either<MyError, String> getCityNameByCode(int code) {
const cities = <int, String>{
1: 'New York',
2: 'Los Angeles',
// 其他城市代码
};
if (cities.containsKey(code)) {
return Right(cities[code]!);
} else {
return Left(
MyError(
key: AppError.NotFound,
message: '[getCityNameByCode] can`t convert code:$code to city name',
),
);
}
}
也可以使用 Either.condLazy
方法来简化条件判断:
return Either.condLazy(
cities.containsKey(code),
() => cities[code]!,
() => MyError(
key: AppError.NotFound,
message: '[getCityNameByCode] can`t convert code:$code to city name',
),
);
高级用法
异步操作
either_dart
提供了 FutureEither
扩展,用于处理异步计算。以下是一个从服务器获取数据并处理响应的例子:
import 'package:either_dart/either.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<Either<AppError, http.Response>> safe(Future<http.Response> request) async {
try {
return Right(await request);
} catch (e) {
return Left(MyError(
key: AppError.BadRequest,
message: "Request executing with errors:$e"));
}
}
Either<AppError, http.Response> checkHttpStatus(http.Response response) {
if (response.statusCode == 200)
return Right(response);
if (response.statusCode >= 500)
return Left(MyError(
key: AppError.ServerError,
message: "Server error with http status ${response.statusCode}"));
return Left(MyError(
key: AppError.BadResponse,
message: "Bad http status ${response.statusCode}"));
}
Future<Either<AppError, dynamic>> parseJson(http.Response response) async {
try {
return Right(json.decode(response.body));
} catch (e) {
return Left(MyError(
key: AppError.JsonParsing,
message: 'failed on json parsing'));
}
}
Future<Either<AppError, Data>> getDataFromServer() {
return
safe(http.get(Uri.parse('some uri')))
.thenRight(checkHttpStatus)
.thenRight(parseJson)
.mapRight(Data.fromJson);
}
示例代码
以下是一个完整的Flutter应用程序示例,展示了如何使用 either_dart
处理来自服务器的数据:
import 'package:either_dart/either.dart';
import 'package:flutter/material.dart';
class Data {
final String data;
Data(this.data);
}
class ServerError {
final String message;
ServerError(this.message);
}
class Client {
bool firstRequest = true;
Future<Either<ServerError, Data>> getDataFromServer() async {
await Future.delayed(const Duration(seconds: 2));
if (!firstRequest) {
return Right(Data("other string"));
} else {
firstRequest = false;
return Left(ServerError("loss connection"));
}
}
}
class WidgetReceivingData extends StatefulWidget {
@override
createState() => _WidgetReceivingDataState();
}
class _WidgetReceivingDataState extends State<WidgetReceivingData> {
final Client apiClient = Client();
Future<Either<ServerError, Data>>? _load;
@override
void initState() {
super.initState();
_load = apiClient.getDataFromServer();
}
void reloadServerData() {
setState(() {
_load = apiClient.getDataFromServer();
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: FutureBuilder<Either<ServerError, Data>>(
future: _load,
builder: (context, snapshot) {
return Center(
child: snapshot.hasData &&
snapshot.connectionState != ConnectionState.waiting
? snapshot.data!.fold<Widget>(
(err) => ServerErrorWidget(err, onReload: reloadServerData),
(data) => DataWidget(data))
: CircularProgressIndicator());
}));
}
}
class DataWidget extends StatelessWidget {
final Data _data;
const DataWidget(this._data);
@override
Widget build(BuildContext context) {
return Text("Data: ${_data.data}");
}
}
class ServerErrorWidget extends StatelessWidget {
final ServerError _error;
final VoidCallback onReload;
const ServerErrorWidget(this._error, {required this.onReload});
@override
Widget build(BuildContext context) {
return Column(mainAxisAlignment: MainAxisAlignment.center, children: [
Text("Error: ${_error.message}"),
SizedBox(height: 20),
ElevatedButton(
onPressed: onReload,
child: Text("Try reload"),
)
]);
}
}
void main() => runApp(MaterialApp(
home: WidgetReceivingData(),
theme: ThemeData(
visualDensity: VisualDensity.adaptivePlatformDensity,
),
));
总结
either_dart
提供了一种简洁且强大的方式来处理同步和异步条件逻辑,特别适用于需要优雅处理错误和异常的场景。通过结合Flutter的UI框架,可以构建出更加健壮和用户友好的应用程序。
更多关于Flutter条件逻辑处理插件either_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter条件逻辑处理插件either_dart的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
在Flutter中,either_dart
是一个用于处理条件逻辑的插件,它提供了一种优雅的方式来处理可能产生多种结果的操作,比如成功或失败的情况。这种处理方式类似于 Rust 语言中的 Result
类型或者 Swift 中的 Result<Success, Failure>
类型。
以下是一个使用 either_dart
的简单示例,展示了如何在 Flutter 应用中进行条件逻辑处理。
首先,你需要在你的 pubspec.yaml
文件中添加 either_dart
依赖:
dependencies:
flutter:
sdk: flutter
either_dart: ^2.0.0 # 确保版本号是最新的
然后,运行 flutter pub get
来安装依赖。
接下来,我们来看一个具体的代码示例。假设我们有一个函数,它尝试从网络获取数据,并返回一个 Either
类型的结果,这个结果可能是成功的数据,也可能是错误信息。
import 'package:flutter/material.dart';
import 'package:either_dart/either.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Either Dart Example'),
),
body: Center(
child: FutureBuilder<Either<String, String>>(
future: fetchData(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return CircularProgressIndicator();
} else if (snapshot.hasError) {
return Text('Error: ${snapshot.error}');
} else {
return EitherWidget(either: snapshot.data!);
}
},
),
),
),
);
}
}
// 模拟一个从网络获取数据的函数
Future<Either<String, String>> fetchData() async {
// 模拟延迟
await Future.delayed(Duration(seconds: 2));
// 这里我们假设获取数据成功
// 你可以根据实际需求修改为返回 Left(error) 来模拟失败
return Right('Data fetched successfully!');
// return Left('Failed to fetch data');
}
class EitherWidget extends StatelessWidget {
final Either<String, String> either;
EitherWidget({required this.either});
@override
Widget build(BuildContext context) {
return either.fold(
(error) => Text('Error: $error'),
(data) => Text('Success: $data'),
);
}
}
在这个示例中:
- 我们定义了一个
fetchData
函数,它模拟从网络获取数据。这个函数返回一个Future<Either<String, String>>
类型的值,其中Left
表示错误,Right
表示成功的数据。 - 在
MyApp
中,我们使用FutureBuilder
来处理异步操作。当数据正在加载时,显示一个CircularProgressIndicator
;如果发生错误,显示错误信息;否则,显示EitherWidget
。 EitherWidget
使用either.fold
方法来根据Either
的类型(Left
或Right
)显示不同的内容。如果是Left
,显示错误信息;如果是Right
,显示成功的数据。
通过这种方式,你可以在你的 Flutter 应用中优雅地处理条件逻辑。