Future的整数值之和

时间:2015-05-14 21:53:13

标签: dart future dart-async

我试图解析HTML文档,获取所有图像源,然后将所有图片的大小加在一起。 解析文档工作正常,获取图像源并获取其大小也是如此。

main(){
  print("Please input an URL");
  var url = stdin.readLineSync();

  getImageUrls(url).then((list) {
    list.forEach((imageUrl) {
      getImageSize(imageUrl).then((r) {
        print("$imageUrl, Size: $r bytes");
      });
    });
  });
}

Future<int> getImageSize(String url){
  final completer = new Completer();
  new StreamController()..stream.listen((str) => completer.complete(imageSize(str)))..add(url);
  return completer.future;
}

imageSize(String url){
  return http.get(url).then((response) => response.bodyBytes.length);
}

我想把每个单独图像的大小一起添加到一个整数中。 我想我可以做这样的事情

main(){
  int total = 0;
  print("Please input an URL");
  var url = stdin.readLineSync();

  getImageUrls(url).then((list) {
    list.forEach((imageUrl) {
      getImageSize(imageUrl).then((r) {
        print("$imageUrl, Size: $r bytes");
        total += r;
      });
    });
  });
  print(total);
}

但是我需要等待getImageUrls完成才能打印出我的总数。

有人能把我推向正确的方向吗?我觉得我错过了一些非常明显的东西。

2 个答案:

答案 0 :(得分:1)

最简单的方法是使用&#34; new&#34; xhr.responseText / async

await

或评论中提到的main() async { int total = 0; print("Please input an URL"); var url = stdin.readLineSync(); var list = await getImageUrls('url'); for(int i = 0; i < list.length; i++) { var imageUrl = list[i]; var r = await getImageSize(imageUrl); print("$imageUrl, Size: $r bytes"); total += r; } print(total); }

Future.wait

答案 1 :(得分:0)

您也可以使用software threads 它们基于相同的Future's(在相同的隔离区中运行),但它们更适用于需要同步和中断某些计算执行的情况。

import "dart:async";

import "package:threading/threading.dart";

main() async {
  await testLoopFutures();
  await testLoopThreads();
}

Future<int> getImageSize(String url) async {
  await new Future.delayed(new Duration(milliseconds: 1000));
  return 1;
}

Future<List<String>> getImageUrls(url) async {
  var result = <String>[];
  for (int i = 0; i < 4; i++) {
    result.add("url $i");
  }

  return result;
}

Future testLoopFutures() async {
  print("================");
  print("Loop futures");
  var sw = new Stopwatch();
  sw.start();
  int total = 0;
  var url = "";
  var list = await getImageUrls(url);
  for (int i = 0; i < list.length; i++) {
    var imageUrl = list[i];
    var r = await getImageSize(imageUrl);
    print("$imageUrl, Size: $r bytes, ${sw.elapsedMilliseconds / 1000} sec");
    total += r;
  }

  sw.start();
  print("total: $total");
  print("Loop futures: ${sw.elapsedMilliseconds / 1000} sec");
}

Future testLoopThreads() async {
  print("================");
  print("Loop threads");
  var sw = new Stopwatch();
  sw.start();
  int total = 0;
  var url = "";
  var list = await getImageUrls(url);
  sw.start();
  var threads = <Thread>[];
  for (int i = 0; i < list.length; i++) {
    Thread thread;
    thread = new Thread(() async {
      var imageUrl = list[i];
      var r = await getImageSize(imageUrl);
      print("$imageUrl, Size: $r bytes, ${sw.elapsedMilliseconds / 1000} sec");
      total += r;
    });

    threads.add(thread);
    await thread.start();
  }

  for (int i = 0; i < list.length; i++) {
    await threads[i].join();
  }

  print("total: $total");
  print("Loop threads: ${sw.elapsedMilliseconds / 1000} sec");
}

输出:

================
Loop futures
url 0, Size: 1 bytes, 1.02 sec
url 1, Size: 1 bytes, 2.021 sec
url 2, Size: 1 bytes, 3.022 sec
url 3, Size: 1 bytes, 4.023 sec
total: 4
Loop futures: 4.023 sec
================
Loop threads
url 0, Size: 1 bytes, 1.068 sec
url 1, Size: 1 bytes, 1.078 sec
url 2, Size: 1 bytes, 1.078 sec
url 3, Size: 1 bytes, 1.078 sec
total: 4
Loop threads: 1.078 sec

当然,您可以使用Future.wait()threads(使用相同的方法)可以使用完整的功能,例如:

  • 睡眠,加入主题
  • 获取,释放锁(互斥锁)
  • 等待,信号和广播事件(条件变量)
  • 中断线程