What is the difference between Sink and Stream in

2020-06-01 01:10发布

问题:

The Google I/O 2018 video about Flutter explains how to use Dart streams to manage state in a Flutter application. The speaker talked about using Sink as input stream and Stream as output stream. What is the difference between Sink and Stream? I searched the documentation but it doesn't say too much thanks.

回答1:

A StreamSink is a StreamConsumer, which means it can take several streams (added by addStream) and processes the events these streams emit.

If it is the StreamSink of a StreamController then all events from the added streams are emitted by the stream created by the StreamController.

This way you can pipe (forward) one or more streams into another one.



回答2:

I will try to explain with a simple example because from that point it is easy to understand.

Sink and Streams are both part of the stream controller. You add a data to the stream controller using sink which can be listened via the stream

Example:

  final _user = StreamController<User>();
  Sink get updateUser => _user.sink;
  Stream<User> get user => _user.stream;

Usage:

  updateUser.add(yourUserObject); // This will add data to the stream.
  user.listen((user) => print(user)); // Whenever a data is added to the stream via sink, it will be emitted which can be listened using the listen method.

You can perform a various number of actions before the stream is emitted. transform method is an example which can be used to transform the input data before it gets emitted.



回答3:

Let us take a simple example of SINKS & STREAMS in Flutter. Please Reade the comments

       class LoginBloc {
          final _repository = Repository();
          final _loginResponse = BehaviorSubject<bool>();  //---->> a simple Sink
          Stream<bool> get isSuccessful => _loginResponse.stream; //-----> Stream linked with above sink

        /*
       *  Below is an async function which uses Repository class
       *  to hit a login API and gets the result in a variable
       *  isUserLoginSuccessful[true/false]. and then Add the result 
       *  into the sink.
       *  now whenever something is added to the sink, a callback is given to
       *  the stream linked to that Sink, which is managed by the framework itself 
       *  
       */

         Future getLoginResponse() async { 
            bool isUserLoginSuccessful = await _repository.processUserLogin();
            _loginResponse.sink.add(isUserLoginSuccessful);
          }

          dispose() {
            _loginResponse.close();
          }
        }

Now, I am using this LoginBloc in Login Screen.

     class Login extends StatelessWidget {
      final LoginBloc loginBloc;  // ----> Here is the Object of LoginBloc
      Login(this.loginBloc);

      void _onClickLoginButton() async {
        // Hit login API
        // fetch Login API response data
        loginBloc.getLoginResponse(); //------> here is the function we are using in Login
      }

      @override
      Widget build(BuildContext context) {
        return StreamBuilder<bool>(    // ----> You need to use a StreamBuilder Widget on the top Root, or according to the Business logic
          stream: loginBloc.isSuccessful,   // ----> here is the stream which is triggered by Sink which is linked by this stream
          builder: (context, snapshot) {
        // DO WHATEVER YOU WANT AFTER CALLBACK TO STREAM
});

i hope this may make your stream & sink concept more clearer.



回答4:

If you are looking for a very basic definitions on stream and sinks, then refer this:

Stream - the conveyor belt is called as a stream StreamController, this is what controls the stream StreamTransformer, this is what processes the input data StreamBuilder, it’s a method that takes stream as an input and provides us with a builder which rebuilds every time there is a new value of a stream sink, the property which takes an input stream, the property which gives the output out of the Stream

For more details,pls refer the following article: