如何等待 Dart 中异步下载的完成或错误?

斯蒂芬·德·卢卡

我想线性地编写一个多阶段的过程(如下所示),它从一个带有进度的文件下载开始:

  /// 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,然后awaitFuture距离StreamSubscription.asFuture

var streamSubscription = response.stream.listen(...);
await streamSubscription.asFuture();

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章