如何在Dart中顺序执行异步功能

时间:2019-12-30 11:05:18

标签: loops asynchronous dart download

我正在使用dart:io的{​​{1}}下载文件,如下所示。

总体思路:

HttpClient

现在我需要在循环中使用此下载功能。

我以前使用过void download(String url, String path, ...) async { var len = await getFileSizeIfExists(path); // download from the last byte ... final file = File(path).openWrite(); ... request.close().then((response) async { await response.listen((data) { file.add(data); // show progress bar }).onDone((_)=> file.close()); }); ... } ,但现在将其更改为forEach,如here所述。问题是要序列化Future.forEach函数。

download

但是它们都立即触发并且都开始下载。这非常糟糕,我需要顺序下载。

我仅在需要访问它们时才使用异步/等待,而不是在各处使用它们(我认为)。 我以为... urls = ['...']; Future<void> process(url) async { await download(url, ...); } Future.forEach(urls, process); ... 应该等待未来的完成。

请告诉我该怎么做才能一个接一个地下载而不杀死服务器。

如果上面提供的代码不够用,则完整代码为here

await

1 个答案:

答案 0 :(得分:1)

信号量可以帮助您。
局部变量maxCount可以调整同时执行的任务数。

示例:

import 'package:http/http.dart' as _http;
import 'package:semaphore/semaphore.dart';

Future<void> main() async {
  final maxCount = 3;
  final s = LocalSemaphore(maxCount);
  _getUrl().forEach((uri) async {
    try {
      await s.acquire();
      await download(uri);
    } finally {
      s.release();
    }
  });
}

Future<void> download(Uri uri) async {
  report('Start download: $uri');
  final resp = await _http.get(uri.toString());
  if (resp.statusCode == 200) {
    report('Downloaded: $uri', _substr(resp.body, 54));
  } else {
    report('ERROR Download: $uri');
  }
}

String _substr(String s, int size) {
  if (s.length > size) {
    return s.substring(0, size);
  }

  return s;
}

void report(String title, [String data = '']) {
  print('${DateTime.now()}: $title');
  if (data.isNotEmpty) {
    print('Data: $data');
  }
}

List<String> _versions = [
  '5.14.2',
  '5.12.0',
  '5.11.0',
  '5.9.7',
  '5.9.2',
  '5.9.0',
  '5.8.0',
  '5.7.0',
  '4.13.0',
  '3.5.17',
];

List<Uri> _getUrl() {
  final result = <Uri>[];
  for (final version in _versions) {
    result.add(Uri.https(
        'ajax.googleapis.com', '/ajax/libs/d3js/${version}/d3.min.js'));
  }

  return result;
}

结果:

2019-12-30 21:11:19.574455: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.14.2/d3.min.js
2019-12-30 21:11:19.599457: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.12.0/d3.min.js
2019-12-30 21:11:19.599457: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.11.0/d3.min.js
2019-12-30 21:11:20.001480: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.14.2/d3.min.js
Data: // https://d3js.org v5.14.2 Copyright 2019 Mike Bostoc
2019-12-30 21:11:20.002480: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.9.7/d3.min.js
2019-12-30 21:11:20.006480: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.12.0/d3.min.js
Data: // https://d3js.org v5.12.0 Copyright 2019 Mike Bostoc
2019-12-30 21:11:20.006480: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.9.2/d3.min.js
2019-12-30 21:11:20.009480: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.11.0/d3.min.js
Data: // https://d3js.org v5.11.0 Copyright 2019 Mike Bostoc
2019-12-30 21:11:20.009480: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.9.0/d3.min.js
2019-12-30 21:11:20.298695: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.9.7/d3.min.js
Data: // https://d3js.org v5.9.7 Copyright 2019 Mike Bostock
2019-12-30 21:11:20.298695: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.8.0/d3.min.js
2019-12-30 21:11:20.305695: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.9.0/d3.min.js
Data: // https://d3js.org v5.9.0 Copyright 2019 Mike Bostock
2019-12-30 21:11:20.305695: Start download: https://ajax.googleapis.com/ajax/libs/d3js/5.7.0/d3.min.js
2019-12-30 21:11:20.308696: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.9.2/d3.min.js
Data: // https://d3js.org v5.9.2 Copyright 2019 Mike Bostock
2019-12-30 21:11:20.308696: Start download: https://ajax.googleapis.com/ajax/libs/d3js/4.13.0/d3.min.js
2019-12-30 21:11:20.577909: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.7.0/d3.min.js
Data: // https://d3js.org v5.7.0 Copyright 2018 Mike Bostock
2019-12-30 21:11:20.577909: Start download: https://ajax.googleapis.com/ajax/libs/d3js/3.5.17/d3.min.js
2019-12-30 21:11:20.587910: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/5.8.0/d3.min.js
Data: // https://d3js.org v5.8.0 Copyright 2019 Mike Bostock
2019-12-30 21:11:20.589910: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/4.13.0/d3.min.js
Data: // https://d3js.org Version 4.13.0. Copyright 2018 Mik
2019-12-30 21:11:20.809315: Downloaded: https://ajax.googleapis.com/ajax/libs/d3js/3.5.17/d3.min.js
Data: !function(){function n(n){return n&&(n.ownerDocument||