typedef CancelCheck = bool Function(); Iterable> _chunked(List list, int size) sync* { if (size <= 0) size = 1; for (var i = 0; i < list.length; i += size) { final end = i + size; yield list.sublist(i, end > list.length ? list.length : end); } } Future runChunked( Iterable items, int chunkSize, Future Function(T item) task, { CancelCheck? isCancelled, }) async { final list = items.toList(); for (final chunk in _chunked(list, chunkSize)) { if (isCancelled?.call() == true) break; await Future.wait( chunk.map((e) async { if (isCancelled?.call() == true) return; await task(e); }), eagerError: false, ); if (isCancelled?.call() == true) break; } }