Error handling 如何在颤振中使用块模式进行错误处理?

Error handling 如何在颤振中使用块模式进行错误处理?,error-handling,flutter,reactive-programming,reactiveui,Error Handling,Flutter,Reactive Programming,Reactiveui,假设我正在使用一个bloc来处理一个网络请求。如果请求失败,处理失败的方式将因平台而异。在我的web应用程序上,我想将用户重定向到错误页面,而在我的IOS应用程序上,我想显示一个对话框 由于bloc应该只用于和共享处理业务逻辑,而错误处理部分与业务逻辑无关,因此我们应该让UI部分负责错误处理 UI可以向bloc发送错误回调,并且bloc将在发生错误时运行该回调。我们还可以通过在不同的平台上发送不同的回调,以特定于平台的方式处理错误 接下来是我的两个问题: 有没有更合适的方法? 如何向集团发送回调

假设我正在使用一个bloc来处理一个网络请求。如果请求失败,处理失败的方式将因平台而异。在我的web应用程序上,我想将用户重定向到错误页面,而在我的IOS应用程序上,我想显示一个对话框

由于bloc应该只用于和共享处理业务逻辑,而错误处理部分与业务逻辑无关,因此我们应该让UI部分负责错误处理

UI可以向bloc发送错误回调,并且bloc将在发生错误时运行该回调。我们还可以通过在不同的平台上发送不同的回调,以特定于平台的方式处理错误

接下来是我的两个问题:

有没有更合适的方法? 如何向集团发送回调? 在flatter中,我们只能在
initState
生命周期方法之后访问bloc(因为我们从构建器上下文中获取bloc,它只在
initState
之后)。那么我们只能在build方法中发送回调

这样,每次重建发生时,我们都会重复地向bloc发送回调(这些重复毫无意义)。 使用react,这种一次性初始化可以在生命周期中完成,例如
componentDidMount

在Flatter中,我们如何实现只运行一次这些初始化的目标?

这是我们在团队中的处理方式:

首先,我们构建主页(导航根目录),如下所示:

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<SuspectEvent, SuspectState>(
        bloc: _bloc,
        builder: (context, state) {
          if (state.cameras.isEmpty) _bloc.dispatch(GetCamerasEvent());

          if (!_isExceptionHandled) {
            _shouldHandleException(
                hasException: state.hasException,
                handleException: state.handleException);
          }
        return Scaffold(
   ...
在我们的街区,我们有:


  @override
  Stream<SuspectState> mapEventToState(SuspectEvent event) async* {
    try {
      if (event is GetCamerasEvent) {

        ... //(our logic)
        yield (SuspectState.newValue(state: currentState)
          ..cameras = _cameras
          ..suspects = _suspects);
      }
      ... //(other events)
    } catch (error) {
      yield (SuspectState.newValue(state: currentState)
        ..hasException = true
        ..handleException = error);
    }
  }


@凌驾
流mapEventToState(SuspectEvent事件)异步*{
试一试{
if(事件为GetCamerasEvent){
…/(我们的逻辑)
收益率(SuspectState.newValue(状态:currentState)
…摄像机=\u摄像机
..嫌疑犯=_嫌疑犯);
}
…/(其他活动)
}捕获(错误){
收益率(SuspectState.newValue(状态:currentState)
…hasException=true
..handleException=错误);
}
}

在我们的错误处理(主页上)中,
InfoDialog
只是一个
showDialog
(来自flatter),它位于任何路径的顶部。因此,只需在根路由上调用警报。

如果将BLoC包装在
scheduleMicrotask
方法中,则可以在
initState
方法中访问该BLoC,以便它在
initState
方法完成后运行:

@覆盖
void initState(){
super.initState();
//在这里进行初始化。
调度微任务(){
//做一些使用集团的事情。
});
}
您还可以查看概述简单的BLoC模式,该模式仅直接在BLoC上调用异步方法,而不是将事件放入接收器

这将允许这样的代码:

  @override
  Widget build(BuildContext context) {
    return BlocBuilder<SuspectEvent, SuspectState>(
        bloc: _bloc,
        builder: (context, state) {
          if (state.cameras.isEmpty) _bloc.dispatch(GetCamerasEvent());

          if (!_isExceptionHandled) {
            _shouldHandleException(
                hasException: state.hasException,
                handleException: state.handleException);
          }
        return Scaffold(
   ...
未来登录(){
试一试{
//做一些网络方面的事情,比如让用户登录或者其他什么。
Bloc.of(context.login)(userController.text,emailController.text);
}服务器上的NotReachableException{
//重定向用户、显示提示或更改此设置
//控件的状态显示错误。这取决于您。
}
}
您可以使用package为一个Bloc创建状态和事件。(在这里,您将通过执行以下操作来声明错误的状态:

  @Data(fields: [DataField<Error>('error')])
  OrderLoadingFailedState,
@Data(字段:[DataField('error')]))
OrderLoadingFailedState,

(如果有人需要一个如何使用它的示例,请告诉我,我将向您展示一个示例)

我认为您高估了传递函数引用的成本。我对flatter和Dart非常陌生,但我正在考虑如何处理一系列错误,以便集团能够接收它们,UI能够进行监听和操作?我也想知道这一点……这里看到一个->