1

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#

 1 year ago
source link: https://blog.51cto.com/xace/5241185
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

      小菜前几天刚学习了 Future 实现异步操作的部分方法,主要包括构造方法和常用的静态方法;小菜今天继续学习 Future 其他知识和 async-await 方式实现异步操作;

Future 嵌套

      小菜在上篇博客中未做 Future 嵌套尝试,有很多场景需要多个异步处理,且每个异步都需要上个异步返回的结果 then() 之后才可以继续,此时可以用 Future 嵌套方式;但如果潜套方法较多可能会对今后的代码维护造成一定影响,即常说到的 Callback hell

_futureMoreThen() {
  Future.delayed(Duration(seconds: 3), () {
    return 'Future.delayed 3s!';
  }).then((val) {
    print('Future -> then(1) -> $val');
    return 'then 1';
  }).then((val) {
    print('Future -> then(2) -> $val');
    return 'then 2';
  }).then((val) {
    print('Future -> then(3) -> $val');
    return 'then 3';
  }).whenComplete(() => print('Future whenComplete!'));
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_0 基础学习 Flutter

_futureMoreThen02() {
  Future.delayed(Duration(seconds: 3), () {
    return 'Future.delayed 3s!';
  }).then((val) {
    print('Future -> then(1) -> $val');
    return Future.delayed(Duration(seconds: 2), () {
      return 'Future.delayed 2s!';
    }).then((val) {
      print('Future -> then(2) -> $val');
      return Future.delayed(Duration(seconds: 2), () {
        return 'Future.delayed 2s!';
      }).then((val) {
        print('Future -> then(3) -> $val');
      });
    });
  }).whenComplete(() => print('Future whenComplete!'));
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Flutter 专题_02

async-await

      Future 也可以通过 async-await 实现异步操作;其使用场景通常是在多个 Future 串联起来,多层级嵌套而导致的 Callback hell,使用 async-await 实现异步;

async

      async 用来修饰的异步方法最终将返回值封装成 Future 对象;

await

      await 会把自动把该方法进入阻塞状态,一直待任务执行完成并返回对应值;

      小菜先尝试了基本的 async-await 用法;

  1. 小菜未采用 asyncawait 关键词,此时 Future.delayed() 返回的是一个 Future 对象,不能同步的获取返回数据;
print(_function01());

_function01() {
  var result = Future.delayed(Duration(seconds: 3), () {
    return 'Future.delayed 3s!';
  }).then((val) => print('Function01 -> then() -> $val'))
    .whenComplete(() => print('Function01 -> whenComplete!'));
  return 'Function01 -> $result';
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Android 小菜鸟_03
2. 小菜仅添加了 async 关键词,将该方法修饰为异步方法,依旧不能直接获取返回数据

print(_function01());

Future<String> _function02() async {
  var result = Future.delayed(Duration(seconds: 3), () {
    return 'Future.delayed 3s!';
  }).then((val) => print('Function02 -> then() -> $val'))
    .whenComplete(() => print('Function02 -> whenComplete!'));
  return 'Function02 -> $result';
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Android 小菜鸟_04
3. 小菜添加了 asyncawait 两个关键词,编译器最终会将其转化为一个 Promise(Future) 的调用链,可以待异步完成之后获取返回结果;此时 Future 不能设置 then() 回调方法等;

print(await _function03());

_function03() async {
  var result = await Future.delayed(Duration(seconds: 3), () {
    return 'Future.delayed 3s!';
  });
  return 'Function03 -> $result';
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Android 小菜鸟_05

  1. 小菜尝试只用 await,此时提示 The await expression can only used in an async functionawait 只能用在 async 方法内部;
  2. 采用 async-await 方式时,对于异常的捕获,可以通过 Future.catchError() 来处理,还可以采用最常用的 try-catch-finally 方式,小菜简单理解对应 then()-catchError()-whenComplete()
await _function04();

_function04(index) async {
  switch (index) {
    case 1:
      await Future.error(ArgumentError.notNull('Input')).catchError((val) => print('Function04 -> $val'));
      break;
    case 2:
      try {
        await Future.error(ArgumentError.notNull('Input'));
      } catch (e) {
        print('Function04 -> catch -> $e');
      } finally {
        print('Function04 -> Finally!');
      }
      break;
  }
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Flutter 专题_06
6. 针对多个 Future 嵌套导致的 Callback hellasync-await 处理方式要简洁一些;

await _functionThen();

_functionThen() async {
  await _itemThen01();
}

_itemThen01() async {
  await Future.delayed(Duration(seconds: 3), () {
    print('Future -> then(1) -> Future.delayed 3s!');
    return _itemThen02();
  });
}

_itemThen02() async {
  await Future.delayed(Duration(seconds: 2), () {
    print('Future -> then(2) -> Future.delayed 2s!');
    return _itemThen03();
  });
}

_itemThen03() async {
  await Future.delayed(Duration(seconds: 2), () {
    print('Future -> then(3) -> Future.delayed 2s!');
    return 'Future.delayed 2s!';
  }).whenComplete(() => print('Future whenComplete!'));
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Flutter 专题_07

      小菜在尝试 async-await 时还遇到 async*,小菜在 bloc 状态管理时使用时都是 async* 和 Stream,小菜简单了解一下相关差异;

async*

      async* 也可以用于异步,方法前使用 async* 关键字可以将该方法标记为异步生成器,返回的是一个 Stream 对象,使用 yield 语句来传递值;

      对于 Stream 的使用,小菜之前有基本的了解,一般通过 skin 添加数据,通过 listen 进行数据监听;

      yield 关键字会向 async* 声明的一步生成器的输出流添加一个值,有点类似 return,但不会终止函数;

 _function06() async* {
  for (int i = 1; i <= 10; i++) {
    await Future.delayed(const Duration(seconds: 1));
    yield i;
  }
}
await for (int num in _function06()) {
  print('current num = $num');
}

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Flutter 小菜_08

_function06().listen((num) => print('current num = $num'));

【Flutter 专题】91 图解 Dart 单线程实现异步处理之 Future (二) #yyds干货盘点#_Android 小菜鸟_09


       Dart async-await 案例尝试


      小菜对 Dart 异步的认知还不完全,接下来会继续尝试 isolate 以及 EventLoop 执行顺序等;如有错误和遗漏请多多指导!

来源: 阿策小和尚


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK