Design-loving front-end engineer
Ryong
Design-loving front-end engineer
์ „์ฒด ๋ฐฉ๋ฌธ์ž
์˜ค๋Š˜
์–ด์ œ
    • Framework
    • React
      • Concept
      • Library
      • Hook
      • Component
      • Test
    • NodeJS
    • Android
      • Concept
      • Code
      • Sunflower
      • Etc
    • Flutter
      • Concept
      • Package
    • Web
    • Web
    • CSS
    • Language
    • JavaScript
    • TypeScript
    • Kotlin
    • Dart
    • Algorithm
    • Data Structure
    • Programmers
    • Management
    • Git
    • Editor
    • VSCode
    • Knowledge
    • Voice
Design-loving front-end engineer

Ryong

Flutter/Concept

[ Flutter ] ์ŠคํŠธ๋ฆผ

2022. 2. 27. 19:16

Stream์ด๋ž€?

๐Ÿ’ฌ  ์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ๋‚˜ ์ด๋ฒคํŠธ๊ฐ€ ๋“ค์–ด์˜ค๋Š” ํ†ต๋กœ๋‹ค.

๐Ÿ’ฌ  ์•ฑ์„ ๋งŒ๋“ค๋‹ค๋ณด๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ผ์ด ๋งŽ์€๋ฐ, ์–ด๋А ํƒ€์ด๋ฐ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ฌ ์ง€ ์•Œ๊ธฐ ์–ด๋ ค์šด ๊ฒƒ์„ ๋น„๋™๊ธฐ ์ž‘์—…์œผ๋กœ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ŠคํŠธ๋ฆผ์ด ์‚ฌ์šฉ๋œ๋‹ค.

๐Ÿ’ฌ  ๊ฐ„๋‹จํ•œ ์˜ˆ๋ฅผ ํ†ตํ•ด ์ŠคํŠธ๋ฆผ์„ ์ดํ•ดํ•ด๋ณด์ž.

import 'dart:async';

void main() {
  // 1์ดˆ๋งˆ๋‹ค ๋ฐ์ดํ„ฐ 1๊ฐœ๋ฅผ ์ตœ๋Œ€ 5๊ฐœ๊นŒ์ง€ ๋งŒ๋“ฆ
  Stream stream = Stream.periodic(Duration(seconds: 1), (x) => x).take(5);
  // ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ
  stream.listen(print);
}

โ—ฝ  ์ŠคํŠธ๋ฆผ์€ ํ•œ์ชฝ ๋์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๋‚ด๊ณ  ๋‹ค๋ฅธ ์ชฝ์—์„œ๋Š” ๋ณด๋‚ธ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ํŒŒ์ดํ”„์™€ ๊ฐ™๋‹ค.

โ—ฝ  ์ŠคํŠธ๋ฆผ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ Single Subscription, ์ฆ‰ ํ•˜๋‚˜์˜ ์ŠคํŠธ๋ฆผ์—๋Š” ํ•˜๋‚˜์˜ ๋ฆฌ์Šค๋„ˆ๋งŒ ๋“ฑ๋ก์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

Stream ๊ฐ’ ๋ณ€๊ฒฝํ•˜๊ธฐ

import 'dart:async';

void main() {
  Stream stream = Stream.periodic(Duration(milliseconds: 200), (x) => x)
    .take(3)
    .map((x) => x + 10);
  
  stream.listen(print);
}

/* 
  10
  11
  12
*/

โ—ฝ  ๊ฐ„๋‹จํ•œ ์ฒ˜๋ฆฌ๋Š” map์„ ํ†ตํ•ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ๋ณต์žกํ•œ ์ฒ˜๋ฆฌ๋Š” StreamTransformer๋ฅผ ํ†ตํ•ด ๊ฐ€๋Šฅํ•˜๋‹ค.

import 'dart:async';

void main() {
  StreamTransformer transform = new StreamTransformer.fromHandlers(
    handleData : (data, sink) {
      sink.add('first $data');
      sink.add('second $data');
    },
  );
  
  Stream stream = new Stream.fromIterable(<dynamic>['hello', 1, 2]);
  stream.transform(transform).listen((event) => print('listen: $event'));
}

/*
  listen: first hello
  listen: second hello
  listen: first 1
  listen: second 1
  listen: first 2
  listen: second 2
*/

 

์‚ฌ์šฉ์ž ์ •์˜ ์ŠคํŠธ๋ฆผ

import 'dart:async';

// async* ํ‚ค์›Œ๋“œ๋Š” yield ํ‚ค์›Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ฒ ๋‹ค๋Š” ๋œป์ด๋‹ค.
Stream<int> createStream(List<int> numbers) async* {
  for (int element in numbers) {
    yield element;
  }
}

void main() {
  Stream<int> stream = crateStream(<int>[1, 2, 3, 4, 5]);
  stream.listen(print);
}

/*
  1
  2
  3
  4
  5
*/

โ—ฝ  async*๋Š” generator๋ฅผ ๋งŒ๋“ ๋‹ค๋Š” ๋œป์ด๋ฉฐ, ์ด๋Š” ์š”์ฒญ์ด ์žˆ์„ ๋•Œ๊นŒ์ง€ ์—ฐ์‚ฐ์„ ๋ฏธ๋ฃจ๋‹ค๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์ฒ˜๋ฆฌํ•œ๋‹ค๋Š” ๋œป์ด๋‹ค.

โ—ฝ  yeild๋Š” ํ•œ ๋ฒˆ ๋ฐ˜ํ™˜ํ•˜๋ฉด ํ•จ์ˆ˜๊ฐ€ ์ข…๋ฃŒ๋˜๋Š” return๊ณผ ๋‹ค๋ฅด๊ฒŒ, ์—ด๋ฆฐ ์ฑ„๋กœ ์กด์žฌํ•˜์—ฌ ํ•„์š”ํ•  ๋•Œ ๋‹ค๋ฅธ ์—ฐ์‚ฐ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

StreamSubscription์ด๋ž€?

๐Ÿ’ฌ  ์œ„์˜ ์˜ˆ์ œ์—์„œ๋Š” listen()์—์„œ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ๊ฒƒ ๊ฐ™์•˜์œผ๋‚˜, ์‹ค์ œ๋กœ๋Š” StreamSubscription์—์„œ ์ด๋ฒคํŠธ ์ฝœ๋ฐฑ์„ ๋‹ค๋ฃฌ๋‹ค.

๐Ÿ’ฌ  listen ์ฝœ๋ฐฑ ํ•จ์ˆ˜๋Š” StreamSubscription์„ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ, StreamSubscription์€ ์•ฑ์ด ์ข…๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€ ํ•ญ์ƒ ์—ด๋ ค ์žˆ์œผ๋ฏ€๋กœ, ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์œ„ํ—˜์ด ์žˆ์–ด ๋‹ซ์•„์ค˜์•ผ ํ•œ๋‹ค.

๐Ÿ’ฌ  ๋˜ํ•œ, onData, onError, onDone์„ ํ†ตํ•ด ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ํ•  ์ˆ˜ ์žˆ๋‹ค.

import 'dart:async';

void main() {
  Stream<int> stream =
    new Stream.periodic(new Duration(milliseconds: 200), (x) => x).take(5);
  
  StreamSubscription subscription = stream.listen(
    (data) => print('data: $data'),  // ๋ฐ์ดํ„ฐ๋ฅผ ํ•˜๋‚˜์”ฉ ์ฒ˜๋ฆฌ
    onDone: () {                     // ๋” ์ด์ƒ ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๋•Œ
      print('Stream Completed');
    },
    onError: (err) {                 // ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ
      print('Error : $err');
    },
  );
}

void dispose() {
  subscription.cancel();
  super.dispose();
}

/*
  data: 0
  data: 1
  data: 2
  data: 3
  data: 4
  Stream Completed
*/

 

StreamController๋ž€?

๐Ÿ’ฌ  StreamController๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์ŠคํŠธ๋ฆผ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋งŒ๋“ค์–ด์กŒ๋‹ค.

๐Ÿ’ฌ  StreamController๋ฅผ ํ†ตํ•ด์„œ ๊ฐ’์„ ๋„ฃ์„ ์ˆ˜ ์žˆ๋Š” ์ŠคํŠธ๋ฆผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๊ณ , ์ด๋Š” stream ์†์„ฑ์„ ํ†ตํ•ด ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค.

 

Broadcast

๐Ÿ’ฌ  ๊ธฐ๋ณธ์ ์œผ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ์ŠคํŠธ๋ฆผ์€ ํ•œ ๊ณณ์—์„œ๋งŒ listen ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ํ•˜๋‚˜์˜ stream์— listen์„ ๋‘ ๊ฐœ ์ด์ƒ ์—ฐ๊ฒฐ์‹œํ‚ค๋ฉด ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๐Ÿ’ฌ  ํ•˜์ง€๋งŒ, broadcast๋ฅผ ํ†ตํ•ด์„œ ํ•˜๋‚˜์˜ stream์— ์—ฌ๋Ÿฌ ๊ฐœ์˜ listen์„ ํ• ๋‹นํ•  ์ˆ˜ ์žˆ๋‹ค.

import 'dart:async';

void main() {
  StreamController<int> controller = new StreamController.broadcast();
  Stream<int> stream = controller.stream;                   // Stream ์ ‘๊ทผ
  
  stream.listen((event) => print('broadcast 1 : $event'));  // Stream ์‚ฌ์šฉ
  stream.listen((event) => print('broadcast 2 : $event'));  // Stream ์‚ฌ์šฉ
  
  controller.sink.add(10);                                  // Stream์— ๊ฐ’ ์ถ”๊ฐ€
  controller.sink.add(20);                                  // Stream์— ๊ฐ’ ์ถ”๊ฐ€
  
  controller.close();                                       // Stream ์ข…๋ฃŒ
}

/*
  broadcast 1 : 10
  broadcast 2 : 10
  broadcast 1 : 20
  broadcast 2 : 20
*/

 

์ €์ž‘์žํ‘œ์‹œ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'Flutter > Concept' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[ Flutter ] ๋ฆฌ์ŠคํŠธ  (0) 2022.02.27
[ Flutter ] ํ™”๋ฉด ํ‘œ์‹œ  (0) 2022.02.27
[ Flutter ] ํ…์ŠคํŠธ  (0) 2022.02.27
[ Flutter ] ํ”Œ๋žซํผ ๋Œ€์‘  (0) 2022.02.24
[ Flutter ] ์ด๋ฏธ์ง€  (0) 2022.02.22
    'Flutter/Concept' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [ Flutter ] ๋ฆฌ์ŠคํŠธ
    • [ Flutter ] ํ™”๋ฉด ํ‘œ์‹œ
    • [ Flutter ] ํ…์ŠคํŠธ
    • [ Flutter ] ํ”Œ๋žซํผ ๋Œ€์‘
    Design-loving front-end engineer
    Design-loving front-end engineer
    ๋””์ž์ธ์— ๊ด€์‹ฌ์ด ๋งŽ์€ ๋ชจ๋ฐ”์ผ ์•ฑ ์—”์ง€๋‹ˆ์–ด Ryong์ž…๋‹ˆ๋‹ค.

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”