簡體   English   中英

如何使用 dartz 重構 flutter 中的功能錯誤處理

[英]How to refactor functional error handling in flutter with dartz

我有兩種方法

@override
  Future<Option<StorageFailure>> init() async {
    final root = await getRootDir();
    return root.fold(
      (failure) => some(failure),
      (dir) {
        final images = Directory("$dir/images");
        final videos = Directory("$dir/videos");
        images.create(); // more error handling here (try|either)
        videos.create();
      },
    );
  }

  @override
  Future<Either<StorageFailure, Directory>> getRootDir() async {
    try {
      final root = await getApplicationDocumentsDirectory();
      return right(Directory("${root.path}/files"));
    } catch (e) {
      return left(StorageFailure(reason: e.toString()));
    }
  }

在折疊后的init方法上,我需要做更多的錯誤處理,但我不喜歡嵌套太多我的代碼。 另外我不知道如何從right的 function 返回Failure

鏈接這些價值觀的更好方法是什么?

Either 最酷的地方在於,您可以鏈接操作並在最后只處理一次錯誤。 如果程序無法獲取根目錄,則永遠不會執行有關創建媒體子目錄的部分。 所以不需要嵌套錯誤處理。

我自己也在學習函數式編程。 所以可能有一個更好的解決方案,但我會這樣做:

// I intentionally added all type annotations for better understanding.
Future<Option<StorageFailure>> init() async {
  final Either<StorageFailure, Directory> root = await getRootDir();
  final Either<StorageFailure, Either<StorageFailure, Success>> result = await root.traverseFuture(createImagesAndVideosSubfolders);
  final Either<StorageFailure, Success> flattenedResult = result.flatMap(id);
  return flattenedResult.fold((failure) => some(failure), (success) => none());
}

Future<Either<StorageFailure, Success>> createImagesAndVideosSubfolders(Directory dir) async {
  try {
    await Directory('${dir.path}/images').create();
    await Directory('${dir.path}/videos').create();
    return right(Success('success'));
  } catch (e) {
    return left(StorageFailure(reason: e.toString()));
  }
}
  1. 獲取根目錄
  2. 創建媒體目錄(如果 getRootDir 失敗,root.traverseFuture 方法只返回現有的 StorageFailure)
  3. 使用 flatMap 和 id function 展平嵌套的 Either。 traverseFuture 方法是期貨的 map 版本。 如果future 也有一個flatMap 等價物,則結果將不會被包裝在一個或中,並且不需要最后一步來展平結果。

您可以通過僅返回 Either 而不是將其轉換為 Option 來進一步簡化 init function。

像這樣:

Future<Either<StorageFailure, Success>> init() async {
  ...
  return result.flatMap(id);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM