Flutter异步async和async*和Stream的简单使用

1,197 阅读1分钟

Flutter异步async和async*的简单使用

async

这里可以看一下简单的demo代码,这里通过Future.delayed执行一个异步任务.

main(List<String> args) {
  print('start');
  Future.delayed(Duration(), () {
    print('run');
  });
  print('end');
}

输出结果为:

start
end
run

这里dart会先执行同步事件,然后再执行异步事件,所以这里就算这里是一个空的duration还是会最后执行.这个结果有时候并不是我们想要的,我们想要end在最后打印,这里我们就可以用async

代码如下:

main(List<String> args) async {
  print('start');
  await Future.delayed(Duration(), () {
    print('run');
  });
  print('end');
}

输出如下:

start
center
end

async*

上面全是废话,我想说的其实是async*

async*

和async的区别在于修饰了async的方法的返回值是Future,async*修饰的方法的返回值是Stream

demo:

main(List<String> args) {
  List<Time> list = [
    Time(value: 1),
    Time(value: 2),
    Time(value: 3),
    Time(value: 4),
    Time(value: 5),
  ];
  ///这里的forEact的返回值是Stream,我们可以通过listen来处理forEach返回的处理好的值.
  forEach(list).listen((event) {
    print(event);
  });
}

Stream<int> forEach(List<Time> list) async* {
  for (int i = 0; i < list.length; i++) {
    yield await list[i].getValue();
  }
}

class Time {
  int value;
  Time({this.value});
  Future getValue() async {
    await Future.delayed(Duration(seconds: 2));
    return value;
  }
}

输出如下:它会每隔两秒输出下一个值

1
2
3
4
5

进阶: 我们可以通过async*, 来处理异步事件队列,比如压缩[图片|视频]数组,然后上传,我们可以通过listen来监听每一个压缩好的文件并执行下一步上传操作. 伪代码:

///压缩工具类
class CompressUtil {
  static Stream<File> compressFileList(List<File> files) async* {
    for (int i = 0; i < files.length; i++) {
      yield await Compress.compressFile(files[index]);
    }
  }
}
///调用代码
CompressUtil.compressFileList(files).listen((file) {
    upload(file);
}).onDone(() {
    print('上传结束');
 });

上面这个是伪代码,并不能真实运行.


完结撒花


上面全是废话

浪费我半天时间,按上面那样搞是有问题的. 最终解决方案:

伪代码

main(List<String> args) async {
  List<File> fileList = [file1, file2, file3, file4];

  ///这里的list就是经过压缩和上传后获得的图片url
  List<String> list = await Stream.fromIterable(fileList)
      .asyncMap((file) => compressFile(file))
      .asyncMap((file) => uploadFile(file))
      .toList();

  /// 后续处理
}

compressFile(File file) async {
  ///压缩操作
  file = await Future.delayed(Duration(seconds: 1), () {
    return file;
  });
  return file;
}

uploadFile(File file) async {
  String url = await upload(file);
  return url;
}

可运行代码

main(List<String> args) async {
  List<int> list = [1, 2, 3, 4, 5, 6];
  print('start');
  List<String> listString = await Stream.fromIterable(list).asyncMap((event) {
    return Future.delayed(Duration(seconds: 1), () {
      return event + 1;
    });
  }).asyncMap((event) {
    return Future.delayed(Duration(seconds: 1), () {
      return event.toString() * event;
    });
  }).toList();
  print(listString);
  print('end');
}