我正在使用flutter bloc来显示下载进度百分比,但我一直遇到这个问题。我认为这个问题出现在onDone
方法中,但我不知道如何解决它。
错误:
- 发生异常。_AssertionError('package:bloc/src/bloc. dart':Assert失败:第137行位置7:'!_isCompleted':emit在事件处理程序正常完成后被调用。这通常是由于事件处理程序中的未等待的将来。请确保等待事件处理程序的所有异步操作,并在异步操作后调用emit()之前使用emit.isDone以确保事件处理程序尚未完成。*
坏
on<Event>((event, emit) {
future.whenComplete(() => emit(...));
});
好
on<Event>((event, emit) async {
await future.whenComplete(() => emit(...));
});
)
代码:
import 'package:bloc/bloc.dart';
import 'package:download_progress_with_bloc/downlaod_file.dart';
import 'package:download_progress_with_bloc/download_event.dart';
import 'package:download_progress_with_bloc/download_state.dart';
import 'package:download_progress_with_bloc/permission_handler.dart';
import 'package:download_progress_with_bloc/store_book_repo.dart';
import 'package:http/http.dart' as http;
class DownloadBloc extends Bloc<DownloadEvent, DownloadState> {
DownloadBloc({required this.storeBookRepo}) : super(DownloadInitial()) {
on<DownloadStarted>(onStarted);
on<DownloadProgressed>(onProgressed);
}
final StoreBookRepo storeBookRepo;
http.StreamedResponse? response;
// StreamController? _controller;
int received = 0;
List<int> bytes = [];
int totalSize = 0;
@override
Future<void> close() {
return super.close();
}
Future<void> onStarted(
DownloadStarted event, Emitter<DownloadState> emit) async {
try {
await PermissionHandler.requestStoragePermission();
response = await downloadFile();
totalSize = response!.contentLength ?? 0;
emit(DownloadInProgress(progress: received, totalSize: totalSize));
response?.stream.asBroadcastStream().listen((value) async {
received += value.length;
bytes.addAll(value);
add(DownloadProgressed(progress: received));
print('received value is $received');
}).onDone(
() async {
await storeBookRepo
.storePdf(
bytes.toString(),
bookTitle: 'bookTitle',
)
.then((value) => emit(DownloadCompleted()));
// emit(DownloadCompleted());
},
);
} catch (e) {
emit(DownlaodFailed(errorMessage: '$e'));
}
}
void onProgressed(DownloadProgressed event, Emitter<DownloadState> emit) {
emit(DownloadInProgress(progress: event.progress, totalSize: totalSize));
}
}
3条答案
按热度按时间7eumitmz1#
如果像这样将
listen
重写为await for
会怎样?s8vozzvw2#
在
on
阻塞之前使用async
,并在未来操作中使用await
mum43rcc3#
你应该使用async和await,这很清楚。但是为什么呢?在完成每个on()方法的运行之前,你可以使用emiteer。之后,bloc将处理或取消该发射器。