IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Dart 异步编程注意事项 -> 正文阅读

[移动开发]Dart 异步编程注意事项

前言

Dart 语言提供了多种异步编程方式,比如 Future,比如async / await,再比如 Stream。如何更好地进行异步编程,我们来看看官方的指引。

相比 Future,优先使用 async / await

异步代码的可读性差和难于调试是臭名昭著的,即便是使用 Future 这样比较好的抽象方式也是一样。 async / await 语法改善了可读性,并且可以在所有 Dart 的控制流的异步代码中使用。下面是一个典型的例子。通过 async / await 语法糖,代码逻辑非常清晰易懂。

// 正确示例
Future<int> countActivePlayers(String teamName) async {
  try {
    var team = await downloadTeam(teamName);
    if (team == null) return 0;

    var players = await team.roster;
    return players.where((player) => player.isActive).length;
  } catch (e) {
    log.error(e);
    return 0;
  }
}

如果使用原始的 Future 方式的话,那代码简直是无法直视 —— 一般人要理清这样的业务逻辑非常困难。
image.png

// 错误示例
Future<int> countActivePlayers(String teamName) {
  return downloadTeam(teamName).then((team) {
    if (team == null) return Future.value(0);

    return team.roster.then((players) {
      return players.where((player) => player.isActive).length;
    });
  }).catchError((e) {
    log.error(e);
    return 0;
  });
}

不要使用没必要的 async

很容易习惯在有异步操作的函数定义时使用 async。但是,在某些情况下却是多余的。如果移除 async 对函数的行为没有影响的话,那么就大胆地移除吧。

// 正确示例
Future<int> fastestBranch(
    Future<int> left, Future<int> right) {
  return Future.any([left, right]);
}

// 错误示例
Future<int> fastestBranch(Future<int> left, Future<int> right) async {
  return Future.any([left, right]);
}

下面是使用 async 的几个场景:

  • 在函数内部有使用到 await —— 这是最常见的情况。
  • 需要异步返回一个错误。使用 async 后再抛出错误会比使用 return Future.error(...) 更简洁。
  • 如果像用 Future 对象包裹一个返回值,那么使用 async 会比 Future.value(...) 更加简洁。
// 正确示例
Future<void> usesAwait(Future<String> later) async {
  print(await later);
}

Future<void> asyncError() async {
  throw 'Error!';
}

Future<void> asyncValue() async => 'value';

避免直接使用 Completer

很对异步编程的新手想写代码尝试产生一个 Future 对象,而 Future 的构造方法似乎满足不了他们的需要,然后他们就会使用 Completer 类来做这样的事情。

// 错误示例
Future<bool> fileContainsBear(String path) {
  var completer = Completer<bool>();

  File(path).readAsString().then((contents) {
    completer.complete(contents.contains('bear'));
  });

  return completer.future;
}

Completer适用于两类底层代码:新的异步原语和不使用 Future 对象的异步接口。大部分代码都应该使用 async / await 或者 Future.then,这是因为他们更加清晰,而且也更容易处理错误。比如下面的代码会更加清晰简洁,个人来说,会更喜欢 async /await的形式。

// 正确示例1:使用 Future.then
Future<bool> fileContainsBear(String path) {
  return File(path).readAsString().then((contents) {
    return contents.contains('bear');
  });
}

// 正确示例2:使用 async / await
Future<bool> fileContainsBear(String path) async {
  var contents = await File(path).readAsString();
  return contents.contains('bear');
}

当处理 FutureOr这种类型时,务必记得检查这个是Future还是对象

FutureOr<T> 声明的对象可能是 Future<T> 或仅仅是 T 类型的对象。因此,在处理这种类型时,通常需要使用 is 检查它到底是Future 对象还是普通对象。对于 FutureOr<int>这类特殊的类型来说,使用is intis Future<int>没什么区别。但是,如果值的类型是 Object或是一个使用 Object实例化的类型参数,那么就有区别了。这是因为如果使用 is T 判断的话,Future<T>对象因为也是 Object,结果会返回 true,比如下面的例子:

// 正确示例
Future<T> logValue<T>(FutureOr<T> value) async {
  if (value is Future<T>) {
    var result = await value;
    print(result);
    return result;
  } else {
    print(value);
    return value;
  }
}

// 错误示例
Future<T> logValue<T>(FutureOr<T> value) async {
  if (value is T) {
    print(value);
    return value;
  } else {
    var result = await value;
    print(result);
    return result;
  }
}

错误示例中,如果传过去的参数是 Future<Object>的话,那么logValue 这个函数会将它当做没有使用 Future 包裹的原始对象进行处理,结果导致程序错误。因此,对 FutureOr<T>是否是异步对象判断时,应当先使用 is Future<T>判断,次序不要弄错了。

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-05-11 16:33:45  更:2022-05-11 16:34:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 1:56:43-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码