Flutter并发控制插件bloc_concurrency的使用

发布于 1周前 作者 h691938207 来自 Flutter

Flutter并发控制插件bloc_concurrency的使用

插件介绍

bloc_concurrency 是一个Dart包,它提供了一些自定义事件转换器,灵感来源于 ember concurrency。它旨在与 bloc 一起工作。更多内容可以访问 bloclibrary.dev

Bloc Concurrency

Event Transformers

bloc_concurrency 提供了一组有意见的事件转换器:

  • concurrent - 并发处理事件
  • sequential - 顺序处理事件
  • droppable - 忽略任何在事件处理期间添加的事件
  • restartable - 只处理最新的事件并取消之前的事件处理器

使用方法

以下是如何在 CounterBloc 中使用 bloc_concurrency 的示例:

import 'package:bloc/bloc.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart';

sealed class CounterEvent {}

final class CounterIncrementPressed extends CounterEvent {}

class CounterBloc extends Bloc<CounterEvent, int> {
  CounterBloc() : super(0) {
    on<CounterIncrementPressed>(
      (event, emit) async {
        await Future.delayed(Duration(seconds: 1));
        emit(state + 1);
      },
      // 指定一个来自 `package:bloc_concurrency` 的自定义事件转换器
      // 在这种情况下,事件将被顺序处理。
      transformer: sequential(),
    );
  }
}

示例代码

下面是一个完整的示例代码,展示了如何创建一个简单的计数器应用,并使用 bloc_concurrency 来管理并发事件:

// ignore_for_file: avoid_print
import 'package:bloc/bloc.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart';

Future<void> tick() => Future<void>.delayed(Duration.zero);

Future<void> main() async {
  /// 创建一个 `CounterBloc` 实例。
  final bloc = CounterBloc();

  /// 订阅状态变化并打印每个状态。
  final subscription = bloc.stream.listen(print);

  /// 与 `bloc` 交互以触发 `state` 变化。
  bloc.add(CounterIncrementPressed());
  await tick();
  bloc.add(CounterIncrementPressed());
  await tick();
  bloc.add(CounterIncrementPressed());
  await tick();

  /// 等待1秒...
  await Future<void>.delayed(const Duration(seconds: 1));

  /// 当不再需要时关闭 `bloc`。
  await bloc.close();

  /// 取消订阅。
  await subscription.cancel();
}

/// `CounterBloc` 将响应的事件。
abstract class CounterEvent {}

/// 通知 bloc 增加状态。
class CounterIncrementPressed extends CounterEvent {}

/// 一个 `CounterBloc`,用于将 `CounterEvent`s 转换为 `int`s。
class CounterBloc extends Bloc<CounterEvent, int> {
  /// `CounterBloc` 的初始状态是 0。
  CounterBloc() : super(0) {
    /// 当添加了 `CounterIncrementPressed` 事件时,
    /// 通过 `state` 属性访问当前 `state`,
    /// 并通过 `emit` 发出新状态。
    on<CounterIncrementPressed>(
      (event, emit) async {
        await Future<void>.delayed(const Duration(seconds: 1));
        emit(state + 1);
      },

      /// 指定一个自定义事件转换器
      /// 在这种情况下,事件将被顺序处理。
      transformer: sequential(),
    );
  }
}

Dart 版本支持

  • Dart 2: >= 2.14

维护者

通过上述内容和示例代码,您可以更好地理解如何在Flutter项目中使用 bloc_concurrency 来管理并发事件。希望这对您有所帮助!


更多关于Flutter并发控制插件bloc_concurrency的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter并发控制插件bloc_concurrency的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter中使用bloc_concurrency插件进行并发控制的代码示例。bloc_concurrency插件允许你自定义和管理BLoC(Business Logic Component)中的并发行为。

首先,确保你已经添加了blocbloc_concurrency依赖到你的pubspec.yaml文件中:

dependencies:
  flutter:
    sdk: flutter
  bloc: ^8.0.0  # 请检查最新版本号
  bloc_concurrency: ^0.2.0  # 请检查最新版本号

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

接下来,让我们看一个具体的例子。假设我们有一个简单的计数器BLoC,我们希望限制并发,以确保在请求处理期间不会发起新的请求。

1. 定义事件和状态

import 'package:flutter_bloc/flutter_bloc.dart';

enum CounterEvent { increment, decrement }

class CounterState {
  final int count;

  CounterState(this.count);

  // 方便的静态方法来创建初始状态
  static final initial = CounterState(0);

  // 方便的方法来根据事件更新状态
  CounterState? reduce(CounterEvent event) {
    if (event == CounterEvent.increment) {
      return CounterState(count + 1);
    } else if (event == CounterEvent.decrement) {
      return CounterState(count - 1);
    }
    return null;
  }
}

2. 创建BLoC类,并使用bloc_concurrency进行并发控制

import 'package:bloc/bloc.dart';
import 'package:bloc_concurrency/bloc_concurrency.dart';
import 'counter_event.dart';
import 'counter_state.dart';

class CounterBloc extends Bloc<CounterEvent, CounterState> {
  CounterBloc() : super(CounterState.initial) {
    on<CounterEvent>(
      _onEvent,
      transformer: (events, nextState) =>
          events.switchMap((event) => just(event).delay(Duration(seconds: 1))), // 模拟网络延迟
      concurrencyMode: ConcurrencyMode.sequential() // 使用顺序并发模式
    );
  }

  void _onEvent(CounterEvent event, Emitter<CounterState> emit) {
    emit(state.reduce(event) ?? state);
  }
}

在这个例子中,我们使用了ConcurrencyMode.sequential(),这意味着BLoC将按顺序处理事件,如果一个新的事件在另一个事件处理期间被添加,它将等待前一个事件处理完成后再处理新的事件。

3. 使用BLoC在Flutter UI中

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'counter_bloc.dart';
import 'counter_event.dart';
import 'counter_state.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('Counter App')),
        body: Center(
          child: BlocProvider(
            create: (context) => CounterBloc(),
            child: CounterView(),
          ),
        ),
      ),
    );
  }
}

class CounterView extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Column(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        BlocBuilder<CounterBloc, CounterState>(
          builder: (context, state) {
            return Text('Count: ${state.count}');
          },
        ),
        SizedBox(height: 20),
        ElevatedButton(
          onPressed: () => context.read<CounterBloc>().add(CounterEvent.increment),
          child: Text('Increment'),
        ),
        SizedBox(height: 10),
        ElevatedButton(
          onPressed: () => context.read<CounterBloc>().add(CounterEvent.decrement),
          child: Text('Decrement'),
        ),
      ],
    );
  }
}

在这个UI中,我们使用了BlocProvider来提供CounterBloc实例,并使用BlocBuilder来监听状态变化。ElevatedButton用于触发事件。

这个示例展示了如何使用bloc_concurrency插件来控制BLoC中的并发行为。通过ConcurrencyMode.sequential(),我们确保了事件按顺序处理,从而避免了并发问题。你可以根据需求选择其他并发模式,如ConcurrencyMode.ignoreConcurrencyMode.restart等。

回到顶部