likes
comments
collection
share

详细了解flutter中的redux epics

作者站长头像
站长
· 阅读数 41

在 Flutter 的状态管理库 Redux 的上下文中,epics 通常指的是使用 redux_epics 库来处理 Redux 中的 side effects。redux_epics 是一个库,它允许你使用 Dart Streams 来处理异步操作,如网络请求、文件 I/O 或其他需要异步处理的任务。

什么是 Epics?

Epics 是一个处理 side effects 的概念,源自于 JavaScript 的 Redux 中的 redux-observable。它们是一种中间件,允许你响应特定的 Actions,并在需要时派发新的 Actions。换句话说,Epics 监听流中的 Actions,执行 side effects 操作,然后派发新的 Actions。

基本概念

  • Action:表示要发生的某个事件或命令。
  • Reducer:接收 Action 并返回新的状态。
  • Epic:监听 Action 流,并根据需要派发新的 Action。Epics 通常用于处理异步操作,如网络请求、延时等。

redux_epics 的使用

1. 安装 redux_epics

首先,在 pubspec.yaml 文件中添加 redux_epics 库:

yaml

dependencies:
  flutter:
    sdk: flutter
  redux: ^5.0.0
  redux_epics: ^2.0.0

然后运行 flutter pub get 来安装依赖。

2. 创建 Epics

假设我们有一个异步操作,例如从 API 获取数据。我们可以创建一个 Epic 来处理这个操作。

dart
import 'package:redux_epics/redux_epics.dart';
import 'package:rxdart/rxdart.dart';

// 定义 Action
class FetchDataAction {}

class FetchDataSuccessAction {
  final String data;
  FetchDataSuccessAction(this.data);
}

class FetchDataErrorAction {
  final dynamic error;
  FetchDataErrorAction(this.error);
}

// 定义 Epic
Stream<dynamic> fetchDataEpic(
  Stream<dynamic> actions,
  EpicStore<dynamic> store,
) {
  return actions.whereType<FetchDataAction>().switchMap((action) {
    // 模拟一个异步网络请求
    return Stream.fromFuture(fetchDataFromApi())
        .map((data) => FetchDataSuccessAction(data))
        .onErrorReturnWith((error) => FetchDataErrorAction(error));
  });
}

// 模拟 API 请求
Future<String> fetchDataFromApi() async {
  await Future.delayed(Duration(seconds: 2)); // 模拟网络延时
  return 'Fetched Data';
}

3. 配置 Store 和 Middleware

将 Epic 添加到 Redux 的 Store 中:

dart
复制代码
import 'package:flutter/material.dart';
import 'package:redux/redux.dart';
import 'package:redux_epics/redux_epics.dart';
import 'package:flutter_redux/flutter_redux.dart';

void main() {
  final epicMiddleware = EpicMiddleware(fetchDataEpic);
  final store = Store<AppState>(
    appReducer,
    initialState: AppState.initial(),
    middleware: [epicMiddleware],
  );

  runApp(MyApp(store: store));
}

class MyApp extends StatelessWidget {
  final Store<AppState> store;

  MyApp({required this.store});

  @override
  Widget build(BuildContext context) {
    return StoreProvider(
      store: store,
      child: MaterialApp(
        home: MyHomePage(),
      ),
    );
  }
}

// 假设有一个简单的状态类
class AppState {
  final String data;

  AppState(this.data);

  factory AppState.initial() => AppState('');
}

// 简单的 Reducer
AppState appReducer(AppState state, dynamic action) {
  if (action is FetchDataSuccessAction) {
    return AppState(action.data);
  }
  return state;
}

class MyHomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Redux Epics Example'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            StoreConnector<AppState, String>(
              converter: (store) => store.state.data,
              builder: (context, data) {
                return Text(data);
              },
            ),
            ElevatedButton(
              onPressed: () {
                StoreProvider.of<AppState>(context).dispatch(FetchDataAction());
              },
              child: Text('Fetch Data'),
            ),
          ],
        ),
      ),
    );
  }
}

工作原理

  1. Action 派发:当用户点击按钮时,FetchDataAction 被派发。
  2. Epic 监听fetchDataEpic 监听到 FetchDataAction,并开始执行异步操作(例如 API 请求)。
  3. 异步操作fetchDataEpic 执行异步操作(例如 fetchDataFromApi),并在操作完成后派发新的 Action,例如 FetchDataSuccessAction
  4. Reducer 更新状态appReducer 监听到 FetchDataSuccessAction,并更新应用状态。
  5. UI 更新StoreConnector 监听到状态变化,并更新 UI。

redux_epics 源码解析

redux_epics 库的核心组件是 EpicEpicMiddlewareEpic 是一个函数,它接受 Action 流和 Store,并返回一个新的 Action 流。EpicMiddleware 是一个 Redux 中间件,它使用 Epics 来处理 Actions。

Epic 的定义

redux_epics 库中,Epic 是一个类型定义如下的函数:

dart
复制代码
typedef Epic<State> = Stream<dynamic> Function(
  Stream<dynamic> actions,
  EpicStore<State> store,
);

这个函数接受一个 Action 流和一个 Store,并返回一个新的 Action 流。EpicStore 是一个包装了 Redux Store 的对象,它提供了对 Store 状态和 dispatch 方法的访问。

EpicMiddleware 的定义

EpicMiddleware 是一个 Redux 中间件,它使用 Epics 来处理 Actions。EpicMiddleware 的实现如下:

dart
复制代码
class EpicMiddleware<State> extends MiddlewareClass<State> {
  final Epic<State> epic;
  final StreamController<dynamic> _actions = StreamController<dynamic>.broadcast();

  EpicMiddleware(this.epic);

  @override
  void call(Store<State> store, action, NextDispatcher next) {
    next(action);
    _actions.add(action);
  }

  void run(Store<State> store) {
    epic(_actions.stream, EpicStore(store)).forEach(store.dispatch);
  }

  void dispose() {
    _actions.close();
  }
}

EpicMiddleware 接受一个 Epic 作为参数,并将它与 Redux Store 连接起来。当一个 Action 被派发时,EpicMiddleware 会将这个 Action 添加到 Action 流中,然后 Epic 处理这个 Action 并派发新的 Actions。

设计模式

redux_epics 中,有几个重要的设计模式:

  1. 观察者模式(Observer Pattern) :Epics 使用 Dart Streams 来监听 Actions,并根据需要派发新的 Actions。这与观察者模式非常类似,Stream 充当主题,Epics 充当观察者。
  2. 中间件模式(Middleware Pattern)EpicMiddleware 是一个典型的中间件,它拦截 Actions 并使用 Epics 来处理它们。
  3. 函数式编程:Epics 使用函数式编程的理念,通过纯函数来处理 Actions 和返回新的 Actions。

总结

  • redux_epics 提供了一种处理 Redux 应用中 side effects 的强大机制。
  • Epics 监听 Action 流,并根据需要执行异步操作或其他 side effects 操作。
  • 通过理解 redux_epics 的工作原理和应用场景,可以更好地管理 Flutter 应用中的 side effects,使代码更加简洁和易于维护。
  • 设计模式如观察者模式、中间件模式和函数式编程理念在 redux_epics 的实现中得到了应用。

扩展补充

Flutter 中的 redux_epics 和 Android 中的 RxJava 在处理异步操作和 side effects 方面有很多相似之处。它们都基于响应式编程理念,通过流的方式处理数据和事件,下面详细对比它们的相似点和不同点。

相似点

1. 响应式编程

  • redux_epics:使用 Dart Streams 处理 Actions 流,监听特定的 Actions 并在需要时执行异步操作或派发新的 Actions。
  • RxJava:使用 Observables 处理数据流,通过订阅模式监听数据变化并执行异步操作。

2. 流的操作符

  • redux_epics:使用 Dart Streams 提供的各种操作符,如 mapswitchMaponErrorReturnWith 等来处理流中的数据。
  • RxJava:提供丰富的操作符,如 mapflatMapswitchMaponErrorReturn 等来转换和处理流中的数据。

3. 中间件机制

  • redux_epics:通过 EpicMiddleware 拦截 Actions 流,使用 Epics 处理这些 Actions 并派发新的 Actions。
  • RxJava:可以与 Android 应用中的中间件(如 Retrofit、OkHttp 等)结合,通过拦截器机制处理网络请求和响应。

4. 异步处理

  • redux_epics:通过 Epics 处理异步操作,如网络请求、文件 I/O 等,并派发新的 Actions 更新状态。
  • RxJava:通过 Observables 和 Schedulers 处理异步操作,进行网络请求、数据库操作等,并更新 UI 或状态。

不同点

1. 应用领域

  • redux_epics:主要用于管理 Flutter 应用中的 Redux 状态,通过 Epics 处理异步 Actions 和 side effects。
  • RxJava:广泛应用于 Android 开发中的各种异步处理场景,如网络请求、并发处理、数据流操作等。

2. 库的实现

  • redux_epics:基于 Dart Streams 和 Redux 进行实现,专注于 Redux 状态管理中的 side effects 处理。
  • RxJava:基于 Java 实现,提供了强大的响应式编程能力,适用于各种异步和并发场景。

3. 使用方式

  • redux_epics:在 Redux 中作为中间件使用,结合 Redux 的 Actions 和 Reducers 处理状态管理。
  • RxJava:可以独立使用或与其他框架(如 Retrofit、Dagger 等)结合,处理各种异步任务。
转载自:https://juejin.cn/post/7386957406499340339
评论
请登录