[Dart]Stream

Liaยท2022๋…„ 8์›” 7์ผ
0

๐ŸŽฏย Dart

๋ชฉ๋ก ๋ณด๊ธฐ
2/3
post-thumbnail

๐Ÿ”ŽStream์ด๋ž€?

์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ๋‚˜ ์ด๋ฒคํŠธ๊ฐ€ ๋“ค์–ด์˜ค๋Š” ํ†ต๋กœ๋ผ๊ณ  ์ƒ๊ฐํ•˜๋ฉด ๋œ๋‹ค.

์•ฑ์„ ๋งŒ๋“ค๋‹ค ๋ณด๋ฉด ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ผ์ด ๋งŽ์€๋ฐ, ์–ด๋Š ํƒ€์ด๋ฐ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ฌ์ง€ ํ™•์‹คํžˆ ์•Œ๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.

์ŠคํŠธ๋ฆผ์€ ์ด์™€ ๊ฐ™์€ ๋น„๋™๊ธฐ ์ž‘์—…์„ ํ•  ๋•Œ ์ฃผ๋กœ ์“ฐ์ธ๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ›์•„์„œ UI์— ๋ณด์—ฌ์ฃผ๋Š” ์ƒํ™ฉ์„ ๊ฐ€์ •ํ•ด๋ณธ๋‹ค๋ฉด,
์–ธ์ œ ๋„คํŠธ์›Œํฌ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค ๋ฐ›์„์ง€ ์•Œ๊ธฐ ์–ด๋ ต๋‹ค. ์‹ ํ˜ธ๊ฐ€ ์•ฝํ•œ ์™€์ดํŒŒ์ด๋ฅผ ์“ธ ์ˆ˜๋„ ์žˆ๊ณ , ๋นต๋นตํ•œ ํ†ต์‹ ์„ ์“ฐ๊ณ  ์žˆ์„ ์ˆ˜๋„ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ์ŠคํŠธ๋ฆผ์€ ๋ฐ์ดํ„ฐ๋ฅผ ๋งŒ๋“œ๋Š” ๊ณณ๊ณผ ์†Œ๋น„ํ•˜๋Š” ๊ณณ์„ ๋”ฐ๋กœ ๋‘ฌ์„œ ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๋‹ค.

Dart์˜ ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์€ Future ๋ฐ Stream ํด๋ž˜์Šค๋กœ ์ฃผ๋กœ ์ฒ˜๋ฆฌํ•˜๋Š”๋ฐ ์ด ๋‘˜์˜ ์ฐจ์ด์ ์„ ์‚ดํŽด๋ณด๋ฉด

Future๋Š” ์ฆ‰์‹œ ์™„๋ฃŒ๋˜์ง€ ์•Š๋Š” ๊ณ„์‚ฐ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ผ๋ฐ˜ ํ•จ์ˆ˜๊ฐ€ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฒฝ์šฐ ๋น„๋™๊ธฐ ํ•จ์ˆ˜๋Š” Future๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋ฉฐ ๊ฒฐ๊ณผ์— ํฌํ•จ๋œ๋‹ค. ๊ฒฐ๊ณผ๊ฐ€ ์ค€๋น„๋˜๋ฉด Future์— ์•Œ๋ ค์ฃผ๋Š” ๊ฒƒ์ด๋‹ค.

->future์€ ์„œ๋ฒ„์— ๋ฐ์ดํ„ฐ๋ฅผ ์š”์ฒญ ํ•œ ํ›„ ์ˆ˜์‹ ํ•œ ๊ฒฐ๊ณผ๊ฐ’์— ๋Œ€ํ•ด์„œ then()์œผ๋กœ ์ „๋‹ฌ

->Stream์€ ๊ตฌ๋…์žํŒจํ„ด(๋˜๋Š” ๊ด€์ฐฐ์ž ํŒจํ„ด)์ด๋‹ค. ๊ตฌ๋…์ž(listen)๊ฐ€ ๊ด€์ฐฐ ๋Œ€์ƒ(stream)์„ ๊ตฌ๋…ํ•˜์—ฌ ๊ด€์ฐฐ ๋Œ€์ƒ์— ๋ณ€ํ™”๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด ๊ตฌ๋…์ž์—๊ฒŒ ๊ทธ ๋ณ€ํ™”๋ฅผ ์•Œ๋ ค์ค€๋‹ค.

๐Ÿ”Ž๋‹จ์ผ ๊ตฌ๋… ์ŠคํŠธ๋ฆผ(Single subscription streams)

๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ ์ข…๋ฅ˜์˜ ์ŠคํŠธ๋ฆผ์—๋Š” ๋” ํฐ ์ „์ฒด์˜ ์ผ๋ถ€์ธ ์ผ๋ จ์˜ ์ด๋ฒคํŠธ๊ฐ€ ํฌํ•จ๋œ๋‹ค.
์ด๋ฒคํŠธ๋Š” ์˜ฌ๋ฐ”๋ฅธ ์ˆœ์„œ๋กœ ๋ˆ„๋ฝ ์—†์ด ์ „๋‹ฌ๋˜์–ด์•ผ ํ•œ๋‹ค.

ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์›น ์š”์ฒญ์„ ๋ฐ›์„ ๋•Œ ์–ป๋Š” ์ŠคํŠธ๋ฆผ. ์ด๋Ÿฌํ•œ ์ŠคํŠธ๋ฆผ์€ ํ•œ ๋ฒˆ๋งŒ๋“ค์„ ์ˆ˜ ์žˆ๋‹ค.

๋‚˜์ค‘์— ๋‹ค์‹œ ๋“ฃ๋Š” ๊ฒƒ์€ ์ดˆ๊ธฐ ์ด๋ฒคํŠธ๊ฐ€ ๋ˆ„๋ฝ๋˜์—ˆ์Œ์„ ์˜๋ฏธํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‚˜๋จธ์ง€ ์ŠคํŠธ๋ฆผ์€ ์˜๋ฏธ๊ฐ€ ์—†๋‹ค.
์ฒญ์ทจ๋ฅผ ์‹œ์ž‘ํ•˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ํŽ˜์น˜ ๋˜์–ด ์ฒญํฌ๋กœ ์ œ๊ณต๋œ๋‹ค.

๐Ÿ”Ž๋ฐฉ์†ก ์ŠคํŠธ๋ฆผ(Broadcast streams)

ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์”ฉ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐœ๋ณ„ ๋ฉ”์‹œ์ง€๋ฅผ ์œ„ํ•œ ๊ฒƒ.

์ด๋Ÿฌํ•œ ์ข…๋ฅ˜์˜ ์ŠคํŠธ๋ฆผ์€ ์˜ˆ๋ฅผ ๋“ค์–ด ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋งˆ์šฐ์Šค ์ด๋ฒคํŠธ์— ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.
์–ธ์ œ๋“ ์ง€ ์ด๋Ÿฌํ•œ ์ŠคํŠธ๋ฆผ ์ฒญ์ทจ๋ฅผ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ฒญ์ทจํ•˜๋Š” ๋™์•ˆ ๋ฐœ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
๋‘˜ ์ด์ƒ์˜ ๋ฆฌ์Šค๋„ˆ๊ฐ€ ๋™์‹œ์— ๋“ค์„ ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด์ „ ๊ตฌ๋…์„ ์ทจ์†Œํ•œ ํ›„ ๋‚˜์ค‘์— ๋‹ค์‹œ๋“ค์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ŠคํŠธ๋ฆผ์€ ์ผ๋ จ์˜ ๋น„๋™๊ธฐ ์ด๋ฒคํŠธ
์š”์ฒญ ์‹œ ๋‹ค์Œ ์ด๋ฒคํŠธ๋ฅผ ๋ฐ›๋Š” ๋Œ€์‹  ์ŠคํŠธ๋ฆผ์ด ์ค€๋น„๋˜๋ฉด ์ด๋ฒคํŠธ๊ฐ€ ์žˆ์Œ์„ ์•Œ๋ ค์ฃผ๋Š” ๋น„๋™๊ธฐ Iterable๊ณผ ๊ฐ™๋‹ค.

๐Ÿ”Ž์ฝ”๋“œ๋กœ ์‚ดํŽด๋ณด๊ธฐ

๋ฆฌ์Šค๋„ˆ๋ฅผ ํ•˜๋‚˜๋งŒ ์„ ์–ธํ•˜๋Š” ๊ฒฝ์šฐ

import โ€˜dart:asyncโ€™;//ํŒจํ‚ค์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๊ธฐ

void main() {
final controller = StreamController(); 
final stream = controller.stream // stream๊ฐ€์ ธ์˜ค๊ธฐ

final streamListener1 = stream.listen((val){
print(โ€˜Listener1 : $valโ€™); //Listener 1:1 โ€ฆ 5 ๊นŒ์ง€ ์ถœ๋ ฅ
//๊ฐ’์„ ๋“ฃ๊ณ  ์žˆ๋‹ค๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ์ด ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค
});
controller.sink.add(1); //๊ฐ’์„ ์ „๋‹ฌ
controller.sink.add(2); //์—ฌ๋Ÿฌ๊ฐœ์˜ ๊ฐ’์„ ์ „๋‹ฌํ•  ์ˆ˜ ์žˆ๋‹ค
controller.sink.add(3);
controller.sink.add(4);
controller.sink.add(5);
}

๋ฆฌ์Šค๋„ˆ๋ฅผ ์—ฌ๋Ÿฌ๊ฐœ ์„ ์–ธํ•˜๋Š” ๊ฒฝ์šฐ-๋ฆฌ์†Œ์Šค๊ฐ€ ํ—ˆ์šฉํ•˜๋Š” ํ•œ ๊ณ„์† ์„ ์–ธํ•  ์ˆ˜ ์žˆ๋‹ค


import โ€˜dart:asyncโ€™;
void main() {
final controller = StreamController(); 
final stream = controller.stream 

final streamListener1 = stream.listen((val){
print(โ€˜Listener1 : $valโ€™); 
});
final streamListener2 = stream.listen((val){
print(โ€˜Listener 2 : $valโ€™);
});

controller.sink.add(1); 
controller.sink.add(2); 
controller.sink.add(3);
controller.sink.add(4);
controller.sink.add(5);
}

์ด๋ ‡๊ฒŒ ๋ฐ”๋กœ ์‹คํ–‰ํ•˜๋ฉด ์•ˆ๋จ

final stream = controller.stream  //๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฆฌ์Šค๋„ˆ๋ฅผ ํ•œ๋ฒˆ๋งŒ ์„ ์–ธ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ๊น€

์—ฌ๋Ÿฌ๋ฒˆ ๊ณ„์† ๋ฆฌ์Šค๋‹์„ ํ•˜๊ณ  ์‹ถ์œผ๋ฉด

final stream = controller.stream.asBroadcastStream();

์ด๋ ‡๊ฒŒ ๋ฐ”๊ฟ”์ค˜์•ผํ•จ

import โ€˜dart:asyncโ€™;
void main() {
final controller = StreamController(); 
final stream = controller.stream.asBroadcastStream();

final streamListener1 = stream.listen((val){
print(โ€˜Listener1 : $valโ€™); 
});
final streamListener2 = stream.listen((val){
print(โ€˜Listener 2 : $valโ€™);
});

controller.sink.add(1); 
controller.sink.add(2); 
controller.sink.add(3);
controller.sink.add(4);
controller.sink.add(5);
}

//์ถœ๋ ฅ๊ฐ’-๋ฒˆ๊ฐˆ์•„๊ฐ€๋ฉด์„œ ๊ฐ’์„ ๋ฆฌ์Šค๋‹ ํ•œ๋‹ค๋Š”๊ฒƒ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค
Listener 1 : 1
Listener 2 : 1
Listener 1 : 2
Listener 2 : 2
Listener 1 : 3
Listener 2 : 3
Listener 1 : 4
Listener 2 : 4
Listener 1 : 5
Listener 2 : 5

์ฆ‰์„์—์„œ Stream๊ฐ’์„ ๋ณ€๊ฒฝํ•˜๋Š” ๋ฒ•-functional programming์˜ ๋Œ€๋ถ€๋ถ„ ํ•จ์ˆ˜๋“ค์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค
streamListener1์—์„œ๋Š” ์ง์ˆ˜๋งŒ ํ”„๋ฆฐํŠธํ•˜๊ณ  ,streamListener2์—์„œ๋Š” ํ™€์ˆ˜๋งŒ ํ”„๋ฆฐํŠธ ํ•˜๋ ค๋ฉด?

import โ€˜dart:asyncโ€™;
void main() {
final controller = StreamController(); 
final stream = controller.stream.asBroadcastStream();

final streamListener1 = stream.where((val)=>val % 2 == 0).listen((val){
print(โ€˜Listener1 : $valโ€™); 
});
final streamListener2 = stream.where((val)=>val % 2 == 1).listen((val){
print(โ€˜Listener 2 : $valโ€™);
});

controller.sink.add(1); 
controller.sink.add(2); 
controller.sink.add(3);
controller.sink.add(4);
controller.sink.add(5);
}

//์ถœ๋ ฅ๊ฐ’
Listener 2 : 1
Listener 1 : 2
Listener 2 : 3
Listener 1 : 4
Listener 2 : 5

functional programming์ฒ˜๋Ÿผ ๋ฐ”๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋Š” ์ˆœ๊ฐ„์— ๋ณ€ํ˜•์„ ์ฃผ๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.
ํ•จ์ˆ˜๋กœ Stream์„ ์ œ๊ณตํ•˜๋Š” ๋ฐฉ๋ฒ•

import โ€˜dart:asyncโ€™;
void main() {
calculate(1).listen((val){
 print(โ€˜calculate(2) : $val โ€™);
}
Stream<int> calculate(int number)async*{
 for (int i =0; i < 5; i+++){ // looping์„ ํ•˜๋ฉด์„œ calculate์— ๋„ฃ์–ด์ค€ ์ฒซ๋ฒˆ์งธ ํŒŒ๋ผ๋ฏธํ„ฐ์™€ ๊ณฑํ•˜๊ธฐ๋ฅผ ํ•˜์—ฌ ๊ณ„์‚ฐ๋œ ๊ฐ’์„ Looping์„ ํ•  ๋•Œ ๋งˆ๋‹ค ๋Œ๋ ค์ค„๊ฒƒ
yield i * number; //yield๊ฐ€ ์‹คํ–‰์ด ๋ ๋•Œ๋งˆ๋‹ค calculateํ•จ์ˆ˜๋ฅผ ๋ฆฌ์Šค๋‹ ํ•˜๊ณ  ์žˆ๋Š” ๋ฆฌ์Šค๋„ˆ์— ๊ฐ’์„ ๋ฟŒ๋ ค์ค„ ์ˆ˜ ์žˆ๋‹ค
}
}
//์ถœ๋ ฅ๊ฐ’
calculate(1) : 0
calculate(1) : 2
calculate(1) : 4
calculate(1) : 6
calculate(1) : 8

์ผ๋ฐ˜์ ์ธ Future์™€ ๊ด€๋ จ๋œ asyncํ•จ์ˆ˜๋ฅผ async*๋กœ ๋œ ํ•จ์ˆ˜์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•-await์‚ฌ์šฉ

import โ€˜dart:asyncโ€™;
void main() {
calculate(2).listen((val){
 print(โ€˜calculate(2) : $val โ€™);
}
Stream<int> calculate(int number)async*{
 for (int i =0; i < 5; i+++){ 
yield i * number; 

await Future.delayed(Duration(second: 1));
}
}
//๊ฐ’์ด 1์ดˆ๋งˆ๋‹ค ๊ณ„์‚ฐ๋˜์–ด ์ถœ๋ ฅ๋œ๋‹ค
calculate(1) : 0
calculate(1) : 2
calculate(1) : 4
calculate(1) : 6
calculate(1) : 8

๐Ÿ“์ฐธ๊ณ ์ž๋ฃŒ

profile
๊บพ์ด์ง€์•Š๊ธฐแ•™เผผ*โ—•_โ—•*เผฝแ•ค

0๊ฐœ์˜ ๋Œ“๊ธ€