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');
}