我有一張圖片,我想縮小到 3 種不同的解析度并上傳到 Cloud Storage。
我有一個Stream<LocalResource> ImageResizer類,它使用縮小原始影像compute()并將它們作為流回傳。
現在我想像這樣處理每個事件(簡化):
List<CloudResource> cloudResources = [];
await for (final resource in ImageResizer(source: file)) {
final id = await cloudStorage.upload(resource);
final url = await cloudStorage.getDownloadableLinkFor(id);
cloudResources.add(CloudResource(id: id, url: url);
}
await database.saveAsset(resources: cloudResources);
這個簡單的實作有效,但我希望它同時作業,因為 ImageResizer不需要等待上傳完成以產生另一個值,并且一切都可以無序處理。
我嘗試了幾種使用Stream.listen(),Stream.mapAsync()和 的方法await Stream.pipe(),使用它們可以實作并發,但是我沒有弄清楚如何等待所有上傳任務完成并cloudResources可以保存的點。
uj5u.com熱心網友回復:
稍微重構一下您的代碼,以便您希望潛在并發的部分位于一個單獨的異步函式中,為 的每個元素呼叫該函式Stream,收集結果Futures,并用于Future.wait等待它們全部完成。例如:
List<CloudResource> cloudResources = [];
Future<void> upload(CloudResource resource) async {
final id = await cloudStorage.upload(resource);
final url = await cloudStorage.getDownloadableLinkFor(id);
cloudResources.add(CloudResource(id: id, url: url);
}
await Future.wait([
await for (final resource in ImageResizer(source: file)
upload(resource),
]);
await database.saveAsset(resources: cloudResources);
uj5u.com熱心網友回復:
我洗掉了您的特定課程,但保留了主要思想。此代碼創建 3 個隔離來并發處理資料。
Stream<String> imageResizer(String startWith) async* {
yield '$startWith 1';
yield '$startWith 2';
yield '$startWith 3';
}
Future<int> upload(String link) async {
print('upload for $link');
await Future.delayed(Duration(seconds: 1));
return link.hashCode;
}
Future<String> getDownloadableLinkFor(int id) async {
print('getDownloadableLinkFor for $id');
await Future.delayed(Duration(seconds: 1));
return ':hash_$id';
}
Future<String> _uploadResource(String resource) async {
print('_uploadResource for $resource');
final id = await upload(resource);
final url = await getDownloadableLinkFor(id);
return '$resource, $id, $url';
}
和代碼呼叫
child: TextButton(
child: Text(gettext("Run example")),
onPressed: () async {
final resolutions = await imageResizer('test').toList();
final tasks = resolutions.map((e) => compute(_uploadResource, e));
final result = await Future.wait(tasks);
// all tasks done, so we can handle result
print('result: $result');
},
),
輸出:
flutter: _uploadResource for test 1
flutter: upload for test 1
flutter: _uploadResource for test 2
flutter: upload for test 2
flutter: _uploadResource for test 3
flutter: upload for test 3
flutter: getDownloadableLinkFor for 1011445077
flutter: getDownloadableLinkFor for 504475879
flutter: getDownloadableLinkFor for 130319434
flutter: result: [test 1, 1011445077, :hash_1011445077, test 2, 504475879, :hash_504475879, test 3, 130319434, :hash_130319434]
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/379115.html
