Код-ревью Senior Dart: Future, Stream, изоляты обновлено
Код-ревью: асинхронный сервис синхронизации
Вопрос
Сервис синхронизации заметок. Найдите проблемы с асинхронностью, ошибками и ресурсами.
class SyncService {
final _controller = StreamController<int>();
Stream<int> get progress => _controller.stream;
Future<void> syncAll(List<Note> notes) async {
notes.forEach((n) async {
await api.upload(n);
});
final parsed = jsonDecode(await api.downloadAll());
for (final n in parsed) {
await db.save(Note.fromJson(n));
_controller.add(1);
}
}
void start() {
syncAll(localNotes);
}
}
Коротко
Правильная версия: загрузка через Future.wait с ограничением параллельности, парсинг в изоляте, пакетная запись, флаг или Completer, не дающий запустить синхронизацию дважды, явная обработка ошибок и dispose с закрытием контроллера. Прогресс через broadcast-поток или ValueNotifier.
Что должен найти ревьюер
- Ошибкастрока 2Single-subscription контроллер, а прогресс слушают несколько экранов: вторая подписка бросит
StateError. Нуженbroadcastили отдельный поток на каждого слушателя. - Ошибкастрока 6
forEachс async-колбэком не ждёт загрузку:syncAllидёт дальше, ошибки загрузки становятся необработанными. - Производительностьстрока 9
jsonDecodeбольшого ответа в UI-изоляте блокирует кадры. Вынести вIsolate.runилиcompute. - Производительностьстрока 11Сохранение по одной записи с
awaitв цикле: медленно. Пакетная запись в транзакции. - Ошибкастрока 17
syncAllбезawaitи обработки ошибки: исключение станет необработанной ошибкой зоны, а повторныйstartзапустит параллельную синхронизацию. - Ошибкастрока 2Контроллер никогда не закрывается: нужен
disposeсервиса с_controller.close().
Разбор
Правильная версия: загрузка через Future.wait с ограничением параллельности, парсинг в изоляте, пакетная запись, флаг или Completer, не дающий запустить синхронизацию дважды, явная обработка ошибок и dispose с закрытием контроллера. Прогресс через broadcast-поток или ValueNotifier.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.