1

我正在为 RxDart 苦苦挣扎(也许只是直接进行 Rx 编程)。我目前有一个有状态的小部件,它在它的didChangeDependencies(). 该调用发出并通过 http 请求获取数据并将其添加到流中。我正在使用BehaviorSubject,这很好用。我有使用 StreamBuilders 的子小部件,它们获取数据没有问题。我的问题在于处理错误。如果我的 http 请求失败,我会使用流水化流,addError('whatever error')但我的子小部件的 StreamBuilder 没有收到该错误。它什么也得不到。

所以我有几个问题。

  1. 这是预期的吗?
  2. 不应该在 StreamBuilder 中进行错误处理吗?理想情况下,如果出现问题,我想在 UI 中显示一些东西,所以不知道该怎么做。
  3. 我可以让我的孩子小部件有状态并使用stream.listen. 我确实收到了那里的错误,但是拥有它和 StreamBuilder 似乎有点过头了。
  4. 我在这里遗漏了一些关于流和错误处理的基本知识吗?

这是我的集团:

final _plans = BehaviorSubject<List<PlanModel>>();
Observable<List<PlanModel>> get plans => _plans.stream;

fetchPlans() async {
    try {
        final _plans = await _planRepository.getPlans();
        _plans.add(_plans);
    }
    on AuthenticationException {
        _plans.addError('authentication error');
    }
    on SocketException {
        _plans.addError('no network connection');
    }
    catch(error) {
        _plans.addError('fetch unsuccessful');
    }
}

简化的父小部件:

class PlanPage extends StatefulWidget {
  @override
  PlanPageState createState() {
    return new PlanPageState();
  }
}

class PlanPageState extends State<PlanPage> {

  @override
  void didChangeDependencies() async {
    super.didChangeDependencies();
    var planBloc = BaseProvider.of<PlanBloc>(context);
    planBloc.fetchPlans();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar( title: const Text('Your Plan') ),
        body: PlanWrapper()
    );
  }
}

带有 StreamBuilder 的简化子小部件:

class PlanWrapper extends StatelessWidget {

  @override
  Widget build(BuildContext context) {
    var planBloc = BaseProvider.of<PlanBloc>(context);

    return StreamBuilder(
      stream: planBloc.plans,
      builder: (BuildContext context, AsyncSnapshot<List<PlanModel>> plans) {
        if (plans.hasError) {
          //ERROR NEVER COMES IN HERE
          switch(plans.error) {
            case 'authentication error':
              return RyAuthErrorCard();
            case 'no network connection':
              return RyNetworkErrorCard();
            default: 
              return RyGenericErrorCard(GeneralException().errorMessages()['message']);
          }
        }
        if (plans.hasData && plans.data.isNotEmpty) {
          return ListView(
            physics: const AlwaysScrollableScrollPhysics(),
            children: _buildPlanTiles(context, plans.data)
          );
        }
        return Center(child: const CircularProgressIndicator());
      }
    );
  }
}
4

1 回答 1

1

RxDart GitHub ( https://github.com/ReactiveX/rxdart/issues/227 )中有一个关于此的问题。BehaviorSubjects 没有向新听众重播错误。

它已在 0.21.0 版中修复。“重大变化:如果最后一个事件也是一个错误,那么 BehaviorSubject 现在将发出一个错误。以前,如果在侦听之前发生错误,则不会通知订阅者该错误。”

于 2019-03-31T15:28:43.397 回答