我想线性地编写一个多阶段的过程(如下所示),它从一个带有进度的文件下载开始:
/// Processes the database, from download to prices processing.
Future<void> updateDatabase() async {
//final fontText = await File('./example/cosmic.flf').readAsString();
//print(art.renderFiglet('updateDatabase'));
// == 1) download
print('1 ======== DOWNLOADING ==========');
try {
await startDownloading();
} catch (err) {}
// == 2) Decompress: Whatever download was ok or not, we decompress the last downloaded zip file we have locally
print('2 ======== DECOMPRESSING ========');
try {
await startDecompressing();
} catch (err) {}
// == i) Stage i, etc.
但是有些东西在我的下载阶段不起作用,因为它开始阶段 2) 前阶段 1) 完成。
我的第一阶段(下载)是这样的:
/// Starts download procress
Future<void> startDownloading() async {
print("startDownloading…");
_state = DownloadState.downloading;
_progress = 0;
notifyListeners();
/// Database string url
final databaseUrlForInstantData = "https://XXX";
try {
final request = Request('GET', Uri.parse(databaseUrlForInstantData));
final StreamedResponse response = await Client().send(request);
final contentLength = response.contentLength;
// == Start from zero
_progress = 0;
notifyListeners();
/// The currently downloaded file as an array of bytes
List<int> bytes = [];
response.stream.listen(
/// = Closure listener for newly downloaded bytes
(List<int> newBytes) {
bytes.addAll(newBytes);
final downloadedLength = bytes.length;
if (contentLength == null) {
_progress = 0;
} else {
_progress = downloadedLength / contentLength;
}
notifyListeners();
print(
'Download in progress $_progress%: ${bytes.length} bytes so far');
},
/// = Download successfully completed
onDone: () async {
_state = DownloadState.downloaded;
notifyListeners();
/// The resulting local copy of the database
final file = await _getDownloadedZipFile();
// == Write to file
await file.writeAsBytes(bytes);
print('Download complete: ${bytes.length} bytes');
},
/// = Download error
onError: (e) {
_state = DownloadState.error;
_error = e.message;
print('Download error at $_progress%: $e');
},
cancelOnError: true,
);
}
// == Catches potential error
catch (e) {
_state = DownloadState.error;
_error = 'Could not download the databse: $e';
print('Download error at $_progress%: $e');
}
}
您的startDownloading
函数在注册回调以侦听Stream
并且不等待Stream
完成后返回。
等待Stream
完成,可以节省StreamSubscription
由归国.listen
,然后await
在Future
距离StreamSubscription.asFuture
:
var streamSubscription = response.stream.listen(...);
await streamSubscription.asFuture();
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句