Dart学习5

85 阅读3分钟

异步 async

异步回调 then

import 'package:dio/dio.dart';

void main() {
  Dio dio = Dio();
  dio.get("https://wpapi.ducafecat.tech/products/categories").then((response) {
    print(response.data);
  });
}

[{id: 34, name: Bag, slug: bag, parent: 0, description: ...

then 的方式异步回调

异步等待 await

import 'package:dio/dio.dart';

void main() async {
  Dio dio = Dio();
  Response<String> response =
      await dio.get("https://wpapi.ducafecat.tech/products/categories");
  print(response.data);
}

[{id: 34, name: Bag, slug: bag, parent: 0, description: ...

async 写在函数定义 await 写在异步请求头

异步返回值

import 'package:dio/dio.dart';

Future<String?> getUrl(String url) async {
  Dio dio = Dio();
  Response<String> response = await dio.get(url);
  return response.data;
}

void main() async {
  var content =
      await getUrl('https://wpapi.ducafecat.tech/products/categories');
  print(content);
}

[{id: 34, name: Bag, slug: bag, parent: 0, description: ...

定义 Future<T> 返回对象

生成器 generate

同步生成器

Iterable<int> naturalsTo(int n) sync* {
  print('start');
  int k = 0;
  while (k < n) {
    yield k++;
  }
  print('end');
}

main(List<String> args) {
  var it = naturalsTo(5).iterator;
  while (it.moveNext()) {
    print(it.current);
  }
}

start
0
1
2
3
4
end

yield 会等待 moveNext 指令

异步生成器

import 'dart:async';

Stream<int> asynchronousNaturalsTo(int n) async* {
  print('start');
  int k = 0;
  while (k < n) {
    yield k++;
  }
  print('end');
}

main(List<String> args) {
  // 流监听
  // asynchronousNaturalsTo(5).listen((onData) {
  //   print(onData);
  // });

  // 流监听 StreamSubscription 对象
  StreamSubscription subscription = asynchronousNaturalsTo(5).listen(null);
  subscription.onData((value) {
    print(value);
    // subscription.pause();
  });
}

start
0
1
2
3
4
end

以流的方式一次性推送

StreamSubscription 对象进行流监听控制

递归生成器

Iterable<int> naturalsDownFrom(int n) sync* {
  if (n > 0) {
    yield n;
    yield* naturalsDownFrom(n - 1);
  }
}

main(List<String> args) {
  var it = naturalsDownFrom(5).iterator;
  while (it.moveNext()) {
    print(it.current);
  }
}

5
4
3
2
1

yield* 以指针的方式传递递归对象,而不是整个同步对象

类型定义 typedef

  • 显示这个函数的输入输出
  • 简化常用函数、类型定义

typedef 定义使用

  • 采用 typedef
typedef MyPrint = void Function(String val);

class PrintClass {
  MyPrint print;
  PrintClass(this.print);
}

main() {
  PrintClass coll = PrintClass((String val) => print(val));
  coll.print('hello world');
}

hello world

未采用 typedef

class PrintClass {
  void Function(String val) print;
  PrintClass(this.print);
}

main() {
  PrintClass coll = PrintClass((String val) => print(val));
  coll.print('hello world');
}

hello world

简化常用类型定义

  • 定义
typedef MapStringAny = Map<String, dynamic>;
typedef MapAnyString = Map<dynamic, String>;
typedef MapStringString = Map<String, String>;
typedef MapStringDouble = Map<String, double>;
typedef MapDoubleString = Map<double, String>;
typedef MapDoubleDouble = Map<double, double>;
typedef MapIntInt = Map<int, int>;
typedef MapIntDouble = Map<int, double>;

typedef ListString = List<String>;
typedef ListInt = List<int>;
typedef ListDouble = List<double>;
typedef ListAny = List<dynamic>;
  • 使用
main() {
  ListString p = [];
  p.add('a');
  p.add('b');
  p.add('c');

  MapStringAny m = {};
  m['a'] = 1;
  m['b'] = 2;
  m['c'] = 3;
}

空安全

  • 减少数据异常错误
  • 提高程序性能

默认不可空

String title = 'ducafecat';

type? 可空

String? title = null;

value! 值保证不为空,主观上

String? title = 'ducafecat';
String newTitle = title!;

value?. 不为空才执行

String? title = 'ducafecat';
bool isEmpty = title?.isEmpty();

value?? 如果空执行

String? title = 'ducafecat';
String newTitle = title ?? 'cat';

late 声明

延迟加载修饰符

声明一个不可空的变量,并在声明后初始化。

late String description;

void main() {
  description = 'Feijoada!';
  print(description);
}

late 类成员延迟初始

class WPHttpService extends GetxService {
  late final Dio _dio;

  @override
  void onInit() {
    ...

    _dio = Dio(options);

    ...
  }

加上 late 后就可以不用构造函数的时候初始化了

List、泛型

  List<String?>? l;
  l = [];
  l.add(null);
  l.add('a');
  print(l);
类型集合是否可空数据项是否可空
List<String>nono
List<String>?yesno
List<String?>noyes
List<String?>?yesyes

Map

  Map<String, String?>? m;
  m = {};
  m['a'] = 'b';
  m['b'] = null;
  print(m);
类型集合是否可空数据项是否可空
Map<String, int>nono*
Map<String, int>?yesno*
Map<String, int?>noyes
Map<String, int?>?yesyes

* 可能返回空

扩展 extension

extension 本质上还是和继承一样扩展了方法。

但这是一种简洁优雅的方式,你可以想想之前继承的繁琐。

示例 扩展日期时间

  • 加入依赖包 pubspec.yaml
dependencies:
  intl: ^0.17.0
  • 编写扩展类 ExDateTime
import 'package:intl/intl.dart';

extension ExDateTime on DateTime {
  /// 方法,格式化日期 yyyy-MM-dd
  String toDateString({String format = 'yyyy-MM-dd'}) =>
      DateFormat(format).format(this);

  // 属性
  int get nowTicket => this.microsecondsSinceEpoch;
}

main() {
  var now = DateTime.now();

  print(now.toDateString());
  print(now.nowTicket);
}

我们给可以扩展类加个前缀 Ex 这样一看就知道是扩展

业务场景

  • 功能函数

  • 视图组件