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 Не е позволено Може
Спиране До заявката за следващата стойност До появата на следващото асинхронно събитие