在StreamSubscription上调用.cancel()可防止其他订阅

时间:2019-10-08 19:50:55

标签: flutter dart rxdart

我的应用程序中发生了一些极其奇怪的行为。下面的代码导致了此问题,之后我还提供了详细的解释。

class SnackBarPageController {
  ....
  ....
  StreamSubscription _snackBarSubscription;

  SnackBarPageController(this.bloc) {
    if (bloc.snackObs.value == null) {
      _snackBarSubscription = bloc.snackObs.listen(showSnackBar);
    } else {
      _snackBarSubscription = bloc.snackObs.skip(1).listen(showSnackBar); //weird bug going on here
    }
  }

  ....
  ....

  void dispose() {
    _snackBarSubscription.cancel(); //causes no further subscriptions to receive data, but only if they use .skip()
  }
}

它在这样的页面上使用:

class ListPage extends StatefulWidget {
  const ListPage();

  @override
  _ListPageState createState() => _ListPageState();
}

class _ListPageState extends State<ListPage> {
  final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey();
  SnackBarPageController snackbarController;
  MyBloc bloc;

  @override
  void didChangeDependencies() {
    super.didChangeDependencies();
    bloc = DI.of(context).get<MyBloc>();

    //the stream subscription is instatiated here!
    snackbarController = SnackBarPageController(
      bloc,
    );
  }

  @override
  void dispose() {
    //the streamsubscription .cancel() method is called here!
    snackbarController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return SafeArea(
      child: Theme(
        data: CommonThemes.getTheme(SectionTheme.MyTheme, context),
        child: Scaffold(
          key: _scaffoldKey,
            ...
          ),
        ),
      ),
    );
  }
}

在此代码中,每次您进入页面时,我都会创建一个StreamSubscription。然后,当您离开页面时,将在StreamSubscription方法中取消.dispose()。如果Observable正在监听的StreamSubscription已经有一个值,那么StreamSubscription会使用.skip(1)跳过第一个值。

当我离开页面并调用dispose()时,我已确认流已关闭。然后,当我返回页面时,StreamSubscription是使用.skip(1)方法创建的,这是正确的行为。

但是,从那以后,使用StreamSubscription创建的新.skip(1)永远不会收到任何数据。好像我什至没有设置订阅。如果我将.skip(1)取出,则不会这样做。

我已经尝试过了,看来如果我不取消.dispose()方法中的订阅,那么一切都会很好。但是,当我确实取消它时,它不起作用。就像我说的,如果我取出.skip(1),一切正常。我可以将.cancel()保留在dispose方法中,没有问题。

是什么原因导致这种行为?

0 个答案:

没有答案