Sobes.tech
Middle

Ի՞նչ են Dart-ի գեներատորները (sync* և async*) և ինչպես են աշխատում:

sobes.tech AI

Պատասխան AI-ից

Dart- ում գեներատորները ֆունկցիաներ են, որոնք վերադարձնում են արժեքների հաջորդականություն՝ նրանց ստեղծման ժամանակ, այլ ոչ թե ամբողջ արդյունքը միանգամից։ Օգտագործվում են sync* բանալի բառը սինխրոն գեներատորների համար և async*՝ ասինխրոնների համար։

Սինխրոն գեներատորներ (sync*)

Նրանք վերադարձնում են Iterable տիպի օբյեկտ։ Օգտագործում են yield բանալի բառը հաջորդ արժեքը տալու համար։ Վերահսկողության հոսքը կանգնեցնում է մինչև հաջորդ արժեքի պահանջը (օրինակ՝ for-in ցիկլում)։

Iterable<int> countUpTo(int max) sync* {
  for (int i = 1; i <= max; i++) {
    yield i; // Արժեքի փոխանցում
  }
}

Ասինխրոն գեներատորներ (async*)

Նրանք վերադարձնում են Stream տիպի օբյեկտ։ Օգտագործում են yield բանալի բառը հաջորդ արժեքը տալու համար։ Հետևյալը yield*-ն է՝ բոլոր արժեքները փոխանցելու համար այլ Stream-ից։ Վերահսկողության հոսքը կանգնեցնում և վերսկսում է նոր ասինխրոն իրադարձության առկայության ժամանակ։

Stream<int> countUpToAsync(int max) async* {
  for (int i = 1; i <= max; i++) {
    await Future.delayed(Duration(milliseconds: 100)); // Ասինխրոն աշխատանք模拟
    yield i; // Արժեքի փոխանցում
  }
}

Ինչպես են աշխատում:

Գեներատոր ֆունկցիայի կանչի ժամանակ, ֆունկցիայի մարմինը անմիջապես չի կատարվում։ Վերադարձվում է օբյեկտ (կամ Iterable, կամ Stream)։ Իրական կատարմանը սկսում է միայն առաջին արժեքը ստանալուց հետո։ Երբ հասնում է yield-ին, արժեքը փոխանցվում է "դրսի" և ֆունկցիայի վիճակը պահվում է։ Ֆունկցիայի մարմինը կանգնեցնում է։ Երբ հաջորդ արժեքը ստանալու փորձ է կատարվում, կատարմանը վերսկսում է այն տեղից, որտեղ կանգնեցվել էր, մինչև հաջորդ yield կամ ֆունկցիայի ավարտը։

Տարբերություններ:

Գծագրություն sync* (Սինխրոն) async* (Ասինխրոն)
Վերադարձվող տիպը Iterable Stream
Բանալի բառեր sync*, yield async*, yield, yield*
await-ի օգտագործում Չի թույլատրվում Կարող է լինել
Կանգնեցում Արժեքի պահանջից առաջ Արժեքի առաջացման ժամանակ