[Dart] ๐Ÿ“š1์ฃผ์ฐจ ์Šคํ„ฐ๋”” - functional programming , asynchronous programming

seunghyoยท2023๋…„ 11์›” 5์ผ
0

Flutter

๋ชฉ๋ก ๋ณด๊ธฐ
1/5
post-thumbnail

Week01 - Dart #3, #4

์ฐธ์กฐ ๊ฐ•์˜
https://www.inflearn.com/course/dart-%EC%96%B8%EC%96%B4-%EC%9E%85%EB%AC%B8#curriculum

Functional Programmming

โœ… asMap(), toSet(), toList()

โœ๏ธ์‹ค์Šต์ฝ”๋“œ

void main() {
  List<String> blackPink = ["๋กœ์ œ", "์ง€์ˆ˜", "์ œ๋‹ˆ", "๋ฆฌ์‚ฌ", "์ œ๋‹ˆ"];
  print(blackPink); //[๋กœ์ œ, ์ง€์ˆ˜, ์ œ๋‹ˆ, ๋ฆฌ์‚ฌ, ์ œ๋‹ˆ]
  print(blackPink.asMap());//{0: ๋กœ์ œ, 1: ์ง€์ˆ˜, 2: ์ œ๋‹ˆ, 3: ๋ฆฌ์‚ฌ, 4: ์ œ๋‹ˆ}
  print(blackPink.toSet());//{๋กœ์ œ, ์ง€์ˆ˜, ์ œ๋‹ˆ, ๋ฆฌ์‚ฌ}

  Map blackPinkMap = blackPink.asMap();
  print(blackPinkMap.keys.toList());//[0, 1, 2, 3, 4]
  print(blackPinkMap.values.toList());//[๋กœ์ œ, ์ง€์ˆ˜, ์ œ๋‹ˆ, ๋ฆฌ์‚ฌ, ์ œ๋‹ˆ]

  Set blackPinkSet = blackPink.toSet();
  print(blackPinkSet.toList());//[๋กœ์ œ, ์ง€์ˆ˜, ์ œ๋‹ˆ, ๋ฆฌ์‚ฌ]

asMap์„ ์‚ฌ์šฉํ•˜๋ฉด map์œผ๋กœ ํ˜•๋ณ€ํ™˜์„ ํ•ด์ค€๋‹ค. key๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์ธ๋ฑ์Šค, value๋Š” ๋ฆฌ์ŠคํŠธ์˜ ๊ฐ’์ด๋‹ค. toSet()์„ ์ด์šฉํ•˜๋ฉด ๋ฆฌ์ŠคํŠธ์—์„œ ์ค‘๋ณต๋œ ๊ฐ’์„ ์ œ๊ฑฐํ•ด์ฃผ๊ณ , set์œผ๋กœ ํ˜•๋ณ€ํ™˜์„ ํ•ด์ค€๋‹ค. ()(Iterable) ํ˜•ํƒœ์—์„œ ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“ค์–ด ์ฃผ๊ธฐ ์œ„ํ•ด toList()๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

โœ… map method ํ™œ์šฉ(List, Map, Set)

  final newBlackPink = blackPink.map((x) {
    return '๋ธ”๋ž™ํ•‘ํฌ $x';
  });
  print(blackPink);// [๋กœ์ œ, ์ง€์ˆ˜, ์ œ๋‹ˆ, ๋ฆฌ์‚ฌ, ์ œ๋‹ˆ]
  print(newBlackPink); //(๋ธ”๋ž™ํ•‘ํฌ ๋กœ์ œ, ๋ธ”๋ž™ํ•‘ํฌ ์ง€์ˆ˜, ๋ธ”๋ž™ํ•‘ํฌ ์ œ๋‹ˆ, ๋ธ”๋ž™ํ•‘ํฌ ๋ฆฌ์‚ฌ, ๋ธ”๋ž™ํ•‘ํฌ ์ œ๋‹ˆ)
  print(newBlackPink.toList());//[๋ธ”๋ž™ํ•‘ํฌ ๋กœ์ œ, ๋ธ”๋ž™ํ•‘ํฌ ์ง€์ˆ˜, ๋ธ”๋ž™ํ•‘ํฌ ์ œ๋‹ˆ, ๋ธ”๋ž™ํ•‘ํฌ ๋ฆฌ์‚ฌ, ๋ธ”๋ž™ํ•‘ํฌ ์ œ๋‹ˆ]

  final newBlackPink2 = blackPink.map((x) => '๋ธ”๋ž™ํ•‘ํฌ $x');
  print(newBlackPink2.toList()); //[๋ธ”๋ž™ํ•‘ํฌ ๋กœ์ œ, ๋ธ”๋ž™ํ•‘ํฌ ์ง€์ˆ˜, ๋ธ”๋ž™ํ•‘ํฌ ์ œ๋‹ˆ, ๋ธ”๋ž™ํ•‘ํฌ ๋ฆฌ์‚ฌ, ๋ธ”๋ž™ํ•‘ํฌ ์ œ๋‹ˆ]

  print(blackPink == blackPink); //true
  print(newBlackPink == blackPink);//false
  print(newBlackPink == newBlackPink2);//false

map ๋ฉ”์†Œ๋“œ๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๊ฐ ๋ฆฌ์ŠคํŠธ์˜ ๋ฉค๋ฒ„๋ฅผ ๋ฐ›์•„ () iterable ํ˜•ํƒœ๋กœ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋‹ค. toList()๋ฅผ ์จ์„œ ๋ฆฌ์ŠคํŠธ๋กœ ๋ณ€ํ˜•์‹œ์ผœ์ฃผ๋ฉด ๋œ๋‹ค. newBlackPink2 ์ฒ˜๋Ÿผ arrowํ•จ์ˆ˜ ํ˜•ํƒœ๋„ ์‚ฌ์šฉ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค. ์ด๋•Œ newBlackPink์™€ newBlackPink2๋Š” ์ถœ๋ ฅ ๊ฐ’์ด ๊ฐ™์ง€๋งŒ, map์„ ์‚ฌ์šฉํ•˜๋ฉด ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ๋กœ ๋งŒ๋“ค์–ด์ง€๋Š” ๊ฒƒ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋น„๊ต๊ฐ’์ด false๋กœ ์ถœ๋ ฅ๋œ๋‹ค.

โœ๏ธ Map์—์„œ ํ™œ์šฉํ•œ ์ฝ”๋“œ


  Map<String, String> harryPotter = {
    'harry potter': 'ํ•ด๋ฆฌ ํฌํ„ฐ',
    'Ron Weasley': '๋ก  ์œ„์ฆ๋ฆฌ',
    'Hermione Granger': 'ํ—ค๋ฅด๋ฏธ์˜จ๋А ๊ทธ๋ ˆ์ธ์ €',
  };
  final result = harryPotter.map((key, vaule) =>
      MapEntry('Harry Potter Character $key', 'ํ•ด๋ฆฌํฌํ„ฐ ์บ๋ฆญํ„ฐ $vaule'));
  print(result);//{Harry Potter Character harry potter: ํ•ด๋ฆฌํฌํ„ฐ ์บ๋ฆญํ„ฐ ํ•ด๋ฆฌ ํฌํ„ฐ, Harry Potter Character Ron Weasley: ํ•ด๋ฆฌํฌํ„ฐ ์บ๋ฆญํ„ฐ ๋ก  ์œ„์ฆ๋ฆฌ, Harry Potter Character Hermione Granger: ํ•ด๋ฆฌํฌํ„ฐ ์บ๋ฆญํ„ฐ ํ—ค๋ฅด๋ฏธ์˜จ๋А ๊ทธ๋ ˆ์ธ์ €}

  final keys = harryPotter.keys
      .map(
        (e) => 'HPC $e',
      )
      .toList();
  final values = harryPotter.values.map((e) => 'ํ•ด๋ฆฌํฌํ„ฐ $e').toList();

  print(keys); //[HPC harry potter, HPC Ron Weasley, HPC Hermione Granger]
  print(values);// [ํ•ด๋ฆฌํฌํ„ฐ ํ•ด๋ฆฌ ํฌํ„ฐ, ํ•ด๋ฆฌํฌํ„ฐ ๋ก  ์œ„์ฆ๋ฆฌ, ํ•ด๋ฆฌํฌํ„ฐ ํ—ค๋ฅด๋ฏธ์˜จ๋А ๊ทธ๋ ˆ์ธ์ €]

โœ๏ธ Set์—์„œ ํ™œ์šฉํ•œ ์ฝ”๋“œ

  final newSet = blackPinkSet
      .map(
        (e) => '๋ธ”๋ž™ํ•‘ํฌ $e',
      )
      .toSet();
  print(newSet);//{๋ธ”๋ž™ํ•‘ํฌ ๋กœ์ œ, ๋ธ”๋ž™ํ•‘ํฌ ์ง€์ˆ˜, ๋ธ”๋ž™ํ•‘ํฌ ์ œ๋‹ˆ, ๋ธ”๋ž™ํ•‘ํฌ ๋ฆฌ์‚ฌ}

โœ… where, reduce

.where()์€ map๊ณผ ์œ ์‚ฌํ•œ๋ฐ, ๊ด„ํ˜ธ ์•ˆ์— ํ•จ์ˆ˜๋ฅผ ๋„ฃ์–ด ์ž‘๋™ํ•œ๋‹ค. ๋ฆฌ์ŠคํŠธ ์•ˆ์„ ๋Œ๋ฉด์„œ true๋‚˜ false๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค. ์ด๋•Œ true๋ฉด ์œ ์ง€ํ•˜๊ณ  false๋ฉด ์ œ๊ฑฐํ•œ๋‹ค. reduce๋ฅผ ์‹คํ–‰ํ•  ๋•Œ prev๋Š” ๋ฆฌํ„ด๊ฐ’(๋งจ ์ฒ˜์Œ ๊ฐ’์€ ์ฒซ๋ฒˆ์งธ value), next๋Š” ๋‹ค์Œ๊ฐ’์ด๋‹ค. ํƒ€์ž…์— ์œ ์˜ํ•ด์•ผํ•œ๋‹ค.

โœ๏ธ where ์‹ค์Šต์ฝ”๋“œ

 List<Map<String, String>> people = [
    {
      'name': '์ง€์ˆ˜',
      'group': '๋ธ”๋ž™ํ•‘ํฌ',
    },
    {
      'name': '๋กœ์ œ',
      'group': '๋ธ”๋ž™ํ•‘ํฌ',
    },
    {
      'name': 'RM',
      'group': 'BTS',
    },
    {
      'name': 'V',
      'group': 'BTS',
    },
  ];
  print(people); //[{name: ์ง€์ˆ˜, group: ๋ธ”๋ž™ํ•‘ํฌ}, {name: ๋กœ์ œ, group: ๋ธ”๋ž™ํ•‘ํฌ}, {name: RM, group: BTS}, {name: V, group: BTS}]
//-----------------------------------------------------------------------
  final blackPinkPeople = people.where((e) => e['group'] == '๋ธ”๋ž™ํ•‘ํฌ');
  final bts = people.where((e) => e['group'] == 'BTS');

  print(blackPinkPeople); //({name: ์ง€์ˆ˜, group: ๋ธ”๋ž™ํ•‘ํฌ}, {name: ๋กœ์ œ, group: ๋ธ”๋ž™ํ•‘ํฌ})
  print(bts);//({name: RM, group: BTS}, {name: V, group: BTS})

โœ๏ธ reduce ์‹ค์Šต์ฝ”๋“œ

  List<String> words = ['์•ˆ๋…•ํ•˜์„ธ์š” ', '์ €๋Š” ', '์ฝ”๋“œํŒฉํ† ๋ฆฌ์ž…๋‹ˆ๋‹ค. '];
  final sentence = words.reduce((prev, next) => prev + next);
  final count = words.fold<int>(0, (prev, next) => prev + next.length);
  print(sentence);//์•ˆ๋…•ํ•˜์„ธ์š” ์ €๋Š” ์ฝ”๋“œํŒฉํ† ๋ฆฌ์ž…๋‹ˆ๋‹ค.
  print(count);//19

โœ… fold, cascading operator

fold๋Š” reduce์™€ ๋‹ฌ๋ฆฌ ๋ฐ˜ํ™˜๊ฐ’์ด ์ •ํ•ด์ง„ ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์„ ์–ธํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ์ฒ˜์Œ prev์—๋Š” ์„ ์–ธํ•ด์ค€ ๊ฐ’์ด ๋˜๊ณ , next๋Š” ๋ฆฌ์ŠคํŠธ์˜ ์ฒซ์งธ๊ฐ’์ด ๋“ค์–ด๊ฐ€๊ฒŒ ๋œ๋‹ค. ์•„๋ฌด ํ˜•ํƒœ๋‚˜ ๋ฆฌํ„ดํ•  ์ˆ˜ ์žˆ๊ณ , ๋ฐ‘์˜ ์‹ค์Šต์ฝ”๋“œ์ฒ˜๋Ÿผ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด ๊ฐ’์„ ๊ตฌํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•˜๋‹ค.

โœ๏ธ fold ์‹ค์Šต์ฝ”๋“œ

void main() {
  List<int> numbers = [1,3,5,7,9];
  final sum = numbers.fold<int>(0,(prev,next)=>prev+next);
  print(sum); //25
}
//______________________________________

  List<String> words = ['์•ˆ๋…•ํ•˜์„ธ์š” ', '์ €๋Š” ', '์ฝ”๋“œํŒฉํ† ๋ฆฌ์ž…๋‹ˆ๋‹ค. '];
  final count = words.fold<int>(0, (prev, next) => prev + next.length);
  print(count);//19

โœ๏ธ cascading operator ์‹ค์Šต์ฝ”๋“œ

๋ฆฌ์ŠคํŠธ ์•ž์— ...์„ ์จ์ฃผ๋ฉด ๋Œ€๊ด„ํ˜ธ([])๋ฅผ ์—†์• ์ค€๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ๋‹ค. ...ํ•œ ๋ฆฌ์ŠคํŠธ๋Š” ๊ธฐ์กด ๋ฆฌ์ŠคํŠธ์™€๋Š” ๋‹ค๋ฅธ ๋ฆฌ์ŠคํŠธ์ด๋‹ค.

  List<int> even = [2, 4, 6, 8];
  List<int> odd = [1, 3, 5, 7];
  print([...even, ...odd]);//[2, 4, 6, 8, 1, 3, 5, 7]
  print(even);//[2, 4, 6, 8]
  print([...even]);//[2, 4, 6, 8]
  print(even == [...even]);//false

โœ… ๋ฐ์ดํ„ฐ์˜ ์ •ํ˜•ํ™”

ํด๋ž˜์Šค๋ฅผ ํ†ตํ•œ JSON ๋ฐ์ดํ„ฐ์˜ ์ •ํ˜•ํ™”๋Š” ์˜คํƒ€ ์ˆ˜์ •, ์ œ๊ฑฐ ๋“ฑ ์ž์œ ๋„๋ฅผ ์ œํ•œํ•˜์—ฌ ๋ฐ์ดํ„ฐ์˜ ๊ตฌ์กฐ๋ฅผ ๋ฏฟ์„ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๋กœ ๋งŒ๋“ค์–ด ์ค„ ์ˆ˜ ์žˆ๋‹ค.

  final parsedPeople =
      people.map((x) => Person(name: x['name']!, group: x['group']!));
  print(parsedPeople);
//(Person(name:์ง€์ˆ˜,group:๋ธ”๋ž™ํ•‘ํฌ), Person(name:๋กœ์ œ,group:๋ธ”๋ž™ํ•‘ํฌ), Person(name:RM,group:BTS), Person(name:V,group:BTS))
class Person {
  final String name;
  final String group;
  Person({
    required this.name,
    required this.group,
  });
  
  String toString() {
    return 'Person(name:$name,group:$group)';
  }
}

์ด๋•Œ toString์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฒฐ๊ณผ๊ฐ€ [Instance of 'Person', Instance of 'Person', Instance of 'Person', Instance of 'Person'] ์ด๋Ÿฐ ์‹์œผ๋กœ ๋‚˜์˜ค๊ธฐ ๋•Œ๋ฌธ์— ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

Async Programming

๐Ÿ’ก ๋™๊ธฐ(synchronous)


ํŠน์ • ์ฝ”๋“œ์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๊ณ  ๋‚œ ํ›„ ๋‹ค์Œ ์ฝ”๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ
์„ค๊ณ„๊ฐ€ ๊ฐ„๋‹จํ•˜๊ณ  ์ง๊ด€์ ์ด์ง€๋งŒ ๊ฒฐ๊ณผ๊ฐ€ ์ฃผ์–ด์งˆ ๋•Œ๊นŒ์ง€ ์•„๋ฌด๊ฒƒ๋„ ๋ชปํ•˜๊ณ  ๋Œ€๊ธฐํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ’ก ๋น„๋™๊ธฐ(asynchronous)


ํŠน์ • ์ฝ”๋“œ์˜ ์‹คํ–‰์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ๋‹ค์Œ ์ฝ”๋“œ๋“ค์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒƒ
๋™๊ธฐ๋ณด๋‹ค ๋ณต์žกํ•˜์ง€๋งŒ, ๊ฒฐ๊ณผ๊ฐ€ ์ฃผ์–ด์ง€๋Š” ๋™์•ˆ ์ž‘์—…์„ ํ•  ์ˆ˜ ์žˆ์–ด ์ž์›์„ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.


CPU์—์„œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฐ€์žฅ ์ž‘์€ ์œ ๋‹›์˜ ๋‹จ์œ„๋Š” ์Šค๋ ˆ๋“œ์ด๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด 1+1์ด๋ผ๋Š” ์ž‘์—…(ํ•˜๋‚˜์˜ ํ•จ์ˆ˜)์„ ์‹คํ–‰ํ•˜๋ฉด ๊ทธ ๊ณ„์‚ฐ์„ CPU๊ฐ€ ๊ณ„์‚ฐ์„ ํ•ด์•ผํ•  ๊ฒƒ์ด๋‹ค. ๊ทธ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๊ธฐ ์ „๊นŒ์ง€๋Š” CPU๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋‹ค. ์ด ์ž‘์—…์ด ์™„๋ฃŒ๋œ ํ›„์—์•ผ ์ž‘์—…์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋‹ค. ๋งŒ์•ฝ ์šฐ๋ฆฌ๊ฐ€ ์„œ๋ฒ„์š”์ฒญ์„ ํ•ด์•ผํ•˜๋Š” ์ƒํ™ฉ์„ ์ƒ๊ฐํ•ด๋ณด์ž. ์ƒ๊ฐ๋ณด๋‹ค ๋งŽ์€ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ์ปดํ“จํ„ฐ์—์„œ ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ , ๊ทธ ์„œ๋ฒ„์—์„œ ์‘๋‹ต์ด ์˜ฌ๋•Œ๊นŒ์ง€ ์‹œ๊ฐ„์„ ๋‚ญ๋น„ํ•ด์•ผํ•  ๊ฒƒ์ด๋‹ค. ์ด ๋น„ํšจ์œจ์ ์ธ ๊ณผ์ •์€ ์˜ˆ์ „ Synchronous Programming์ด ์ดˆ๋ž˜ํ•˜๋˜ ๋‹จ์ ์ด๋‹ค. Asynchronous Programming์€ ์„œ๋ฒ„ ์š”์ฒญ์„ ๋ณด๋‚ธ ์ˆœ๊ฐ„ CPU๊ฐ€ ๋‹ค๋ฅธ ์ž‘์—…์„ ๋ฐ›์„ ์ˆ˜ ์žˆ๋Š” ์ƒํƒœ๊ฐ€ ๋˜์–ด ๋” ํšจ์œจ์ ์œผ๋กœ CPU๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ๋‚ญ๋น„ํ•˜๋Š” ์‹œ๊ฐ„์„ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.


โœ… Future

future๋ฅผ ์‚ฌ์šฉํ•ด ๋ฏธ๋ž˜์— ๋ฐ›์•„์˜ฌ ๊ฐ’์„ ์ €์žฅํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋“  ํƒ€์ž…์„ ๋‹ค future๋กœ ๋ณ€๊ฒฝ๊ฐ€๋Šฅํ•˜๋‹ค. async programming์ด ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜์ธ future delayed๋Š” ๋‘ ๊ฐœ์˜ ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ๋ฐ›๋Š”๋‹ค. 1๋ฒˆ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์ง€์—ฐ์„ ํ•˜๋Š” ์‹œ๊ฐ„, 2๋ฒˆ ํŒŒ๋ผ๋ฏธํ„ฐ๋Š” ์‹คํ–‰ํ•  ํ•จ์ˆ˜๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

  Future<String> name = Future.value('์ฝ”๋“œํŒฉํ† ๋ฆฌ');
  Future<int> number = Future.value(1);
  Future<bool> isTrue = Future.value(true);

  addNumbers(1, 1);
}

void addNumbers(int a, int b) {
  print('๊ณ„์‚ฐ์ค‘ : $a + $b');
  Future.delayed(Duration(seconds: 2), () {
    print("๊ณ„์‚ฐ ์™„๋ฃŒ: $a+ $b = ${a + b}");
  });
  print('ํ•จ์ˆ˜ ์™„๋ฃŒ'); //2์ดˆ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๋™์•ˆ ์‹คํ–‰๋˜๋Š” ์ฝ”๋“œ.

์œ„์˜ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ์‹œํ‚จ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ž

๊ณ„์‚ฐ์ค‘ : 1 + 1
ํ•จ์ˆ˜ ์™„๋ฃŒ
(2s ๋’ค)
๊ณ„์‚ฐ ์™„๋ฃŒ: 1+ 1 = 2

ํ•จ์ˆ˜์™„๋ฃŒ๋ผ๋Š” ๋ฌธ๊ตฌ๋Š” ์ œ์ผ ๋’ค์— ์žˆ์ง€๋งŒ, ๋”œ๋ ˆ์ด๋œ ์ฝ”๋“œ๋ณด๋‹ค ๋จผ์ € ์‹คํ–‰๋œ๋’ค, ๋”œ๋ ˆ์ด์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋œ๋‹ค. CPU๊ฐ€ ์ผ์„ ํ•˜์ง€ ์•Š๋Š” ์ˆœ๊ฐ„์— ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ง  ๊ฒƒ์ด๋‹ค.

โœ… await

await๋ฅผ ์‚ฌ์šฉํ•œ ํ•จ์ˆ˜๋Š” ๋ฌด์กฐ๊ฑด async ํ•จ์ˆ˜์ด์–ด์•ผ ํ•˜๊ณ , async ํ•จ์ˆ˜๋Š” ๋ฌด์กฐ๊ฑด Future๋ฅผ ๋ฐ˜ํ™˜ํ•ด์•ผ ํ•œ๋‹ค await ํ‚ค์›Œ๋“œ๋ฅผ ๋งŒ๋‚˜๋ฉด ํ•ด๋‹น ํ•จ์ˆ˜๋ฅผ ์ž ์‹œ ์ •์ง€ํ•˜๊ณ , await ํ‚ค์›Œ๋“œ๊ฐ€ ๋ถ™์€ ๋™์ž‘์ด ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ๋‹ค.

Future<void> addNumbers(int a, int b) async {
  print('๊ณ„์‚ฐ์ค‘ : $a + $b');
  await Future.delayed(Duration(seconds: 2), () {
    print("await ๊ณ„์‚ฐ ์™„๋ฃŒ: $a+ $b = ${a + b}");
  });

  print('ํ•จ์ˆ˜ ์™„๋ฃŒ');

๐Ÿ—’๏ธ ์ถœ๋ ฅ

๊ณ„์‚ฐ์ค‘ : 2 + 2
await ๊ณ„์‚ฐ ์™„๋ฃŒ: 2+ 2 = 4
ํ•จ์ˆ˜ ์™„๋ฃŒ

CPU๋Š” await ํ•˜๋Š” ์ค‘์—๋„ ๋‹ค๋ฅธ ์ž‘์—…์„ ํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

void main() {
  Future<String> name = Future.value("์ฝ”๋“œํŒฉํ† ๋ฆฌ");
  Future<int> number = Future.value(1);
  Future<bool> isTrue = Future.value(true);

  addNumbers(1, 1);
  addNumbers(2, 2);
}

void addNumbers(int number1, int number2) async {
  print("๊ณ„์‚ฐ์‹œ์ž‘: $number1 + $number2");

  await Future.delayed(Duration(seconds: 2), () {
    print("๊ณ„์‚ฐ ์™„๋ฃŒ: $number1 + $number2 = ${number1 + number2}");
  });

  print("ํ•จ์ˆ˜์™„๋ฃŒ");
}

ํ•ด๋‹น ์ฝ”๋“œ์—์„œ addNumbers(2,2)๋Š” await ํ•จ์ˆ˜์—์„œ ๋Œ€๊ธฐํ•˜๋Š” ์ค‘์— ์‹คํ–‰์ด ๋œ๋‹ค. ๋งŒ์•ฝ ์—ฌ๊ธฐ์„œ addNumbers(2,2)์—์„œ๋„ ๋Œ€๊ธฐ๋ฅผ ์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด main๋„ ์œ ์‚ฌํ•˜๊ฒŒ ๋ฐ”๊พธ์–ด์ฃผ๋ฉด ๋œ๋‹ค. async ์ž…๋ ฅ ํ›„ Future<void> addNumbers~ ์ด๋Ÿฐ์‹์œผ๋กœ ํ•จ์ˆ˜๋ฅผ Future๋กœ ๊ฐ์‹ธ๋‘” ๋’ค, addNumbers๋ฅผ main์—์„œ ์‚ฌ์šฉ์‹œ awai๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

void main() async {
  Future<String> name = Future.value("์ฝ”๋“œํŒฉํ† ๋ฆฌ");
  Future<int> number = Future.value(1);
  Future<bool> isTrue = Future.value(true);

  await addNumbers(1, 1);
  await addNumbers(2, 2);
}

Future<void> addNumbers(int number1, int number2) async {
  print("๊ณ„์‚ฐ์‹œ์ž‘: $number1 + $number2");

  await Future.delayed(Duration(seconds: 2), () {
    print("๊ณ„์‚ฐ ์™„๋ฃŒ: $number1 + $number2 = ${number1 + number2}");
  });

  print("ํ•จ์ˆ˜์™„๋ฃŒ");
}

โœ… Stream

dart:async ๋กœ importํ•ด์˜จ ๋’ค, StramController๋กœ stream์„ ํ˜ธ์ถœํ•œ๋‹ค. listen์„ ํ†ตํ•ด listener์—๊ฒŒ ๊ฐ’๋“ค์„ ์ „๋‹ฌํ•œ๋‹ค.

import "dart:async";

void main(){
  final controller = StreamController();
  final stream = controller.stream;

  final streamListener1 = stream.listen((val){
    print("Listener 1 : $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 1 : 2
Listener 1 : 3
Listener 1 : 4
Listener 1 : 5

์ปจํŠธ๋กค๋Ÿฌ ์ŠคํŠธ๋ฆผ์„ ๊ฐ€์ ธ์˜ค๋ฉด ๊ธฐ๋ณธ์ ์œผ๋กœ ํ•œ๋ฒˆ ๋ฆฌ์Šค๋‹์„ ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฆฌ์†Œ์Šค๊ฐ€ ์ƒ๊ธด๋‹ค. ์ด๋•Œ asBroadcastStream์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋ถ™์—ฌ์ฃผ๊ณ  ์ŠคํŠธ๋ฆผ์„ BroadcastSream์œผ๋กœ ๋ณ€๊ฒฝํ•ด์ฃผ๋ฉด ๊ฐ„๋‹จํ•˜๊ฒŒ ์—ฌ๋Ÿฌ๋ฒˆ ๋ฆฌ์Šค๋‹์„ ํ•  ์ˆ˜ ์žˆ๋Š” ์ŠคํŠธ๋ฆผ์„ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

  final controller = StreamController();
  final stream = controller.stream.asBroadcastStream();

  final streamListener1 = stream.listen((val) {
    print("Listener 1 : $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

์ฆ‰์„์—์„œ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ ๊ฐ’์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, where์„ ์‚ฌ์šฉํ•ด ๋ฐ”๋กœ ๋ฐ์ดํ„ฐ๊ฐ€ ๋“ค์–ด์˜ค๋Š” ์ˆœ๊ฐ„์— ๋ณ€ํ˜•์„ ์ฃผ๊ฑฐ๋‚˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค๋ฃฐ ์ˆ˜ ์žˆ๋‹ค.

  final controller = StreamController();
  final stream = controller.stream.asBroadcastStream();

  final streamListener1 = stream.where((val) => val % 2 == 0).listen((val) {
    print("Listener 1 : $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

โœ…Yield

ํ•จ์ˆ˜์—์„œ return์„ ํ•˜๋ฉด ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ณ  ์ข…๋ฃŒํ•œ๋‹ค. ์ŠคํŠธ๋ฆผ์„ ๋Œ๋ ค์ฃผ๊ณ  ์‹ถ๋‹ค๋ฉด future<>๋ฅผ stream<>์œผ๋กœ, async๋ฅผ async*๋กœ, return์„ yield๋กœ ๋ณ€๊ฒฝํ•˜๋ฉด ๋œ๋‹ค.

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;
  }
}

๐Ÿ—’๏ธ ์ถœ๋ ฅ

calculate(2) : 0
calculate(2) : 2
calculate(2) : 4
calculate(2) : 6
calculate(2) : 8

async*์—์„œ๋„ await ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.


Stream<int> calculate(int number) async* {
  for(int i = 0; i < 5; i++) {
    yield i * number;
  }

  await Future.delayed(Duration(seconds : 3));
}

stream์ด ์‹คํ–‰์‹œ for ๋ฃจํ”„๊ฐ€ ์ข…๋ฃŒ๋œ ๋’ค 3์ดˆ ํ›„์— ์ฝ”๋“œ๊ฐ€ ์ข…๋ฃŒ๋œ๋‹ค.


ํ•œ ์ŠคํŠธ๋ฆผ์ด ๋๋‚œ ๋’ค ๋‹ค์Œ ์ŠคํŠธ๋ฆผ์„ ์ง„ํ–‰์‹œํ‚ค๊ณ  ์‹ถ๋‹ค๋ฉด, yield*๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์‹คํ–‰์‹œ ํ•ด๋‹น ์ŠคํŠธ๋ฆผ์ด ๋ชจ๋“  ๊ฐ’์„ ๊ฐ€์ ธ์˜จ ๋’ค์— ์ŠคํŠธ๋ฆผ์ด ์ข…๋ฃŒ๋˜๋ฉด, ๋‹ค์Œ ์ŠคํŠธ๋ฆผ์ด ์ง„ํ–‰๋œ๋‹ค.

void main() {
  playAllStream().listen((val){
    print(val);
  });
}

Stream<int> playAllStream() async* {
  yield* calculate(1);
  yield* calculate(1000);
}

Stream<int> calculate(int number) async* {
  for(int i = 0; i < 5; i++) {
    yield i * number;
  }

  await Future.delayed(Duration(seconds : 1));
}

๐Ÿ—’๏ธ ์ถœ๋ ฅ

0
1
2
3
4
0
1000
2000
3000
4000

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