等待异步
有时候执行某个动作,需要等到另一个事件结束,可以用Completer类。
常见的有:
执行某个动作,需要弹窗等待用户选择某条件后再执行后续代码,
//事例
var c = Completer<bool>();
Dialogs.tipsCard(title, tip,
failMsg: '',
actions: [i18n.ok],
callback: (index) => c.complete(true),
dismissCallBack: () {
if (!c.isCompleted)
c.complete(false);
},
);
return c.future;
其他:
Completer
Completer允许你做某个异步事情的时候,调用c.complete(value)方法来传入最后要返回的值。最后通过c.future的返回值来得到结果,(注意:宣告完成的complete和completeError方法只能调用一次,不然会报错)。看下面的例子更容易理解。
1 | test() async { |
怎么将一个Callback回调转化成Future同步方法(Callback to Future),可以配套async / await去使用呢?
使用场景:dio请求使用call,但外部基本还是习惯使用future方式,为了减少接口的改动,使用callback转future方式。
参考文章:Flutter&Dart Callback转Future
compute
在一个页面中做耗时比较大的运算时,就算用了async / await异步处理, ui页面的动画还是会卡顿,因为还是在这个UI线程中做运算,异步只是说我可以先运行其他的,等我这边有结果再返回,但是,记住,我们的计算仍旧是在这个UI线程,仍会阻塞UI的刷新,异步只是在同一个线程的并发操作。
要解决这个卡顿问题,可以把运算移到另一个线程中,在dart中,这里不是称呼线程,是Isolate,直译叫做隔离,是因为隔离不共享数据,每个隔离中的变量都是不同的,不能相互共享。
Isolate的操作比较复杂,dart中封装了一层简单的实现
1 | /// package:flutter/foundation.dart |
使用方法
1 | import 'package:flutter/foundation.dart'; |
简单来讲就是运行var res = await compute( callback , val )函数。callback的传入参数是val, return的数据就是callback的res;
使用场景
- 方法执行在几毫秒或十几毫秒左右的,应使用Future
- 如果一个任务需要几百毫秒或之上的,则建议compute(只有一次返回)或Isolate(用于订阅或有多次返回的)
Flutter/Dart :如何在app启动前等待异步任务?
我在一个dart应用程序上工作,我想获取缓存(SharedPreferences)中存在的数据,然后在应用程序的UI (主屏幕)上显示它。
问题:由于SharedPreferences是一个等待调用,我的主页加载,试图读取数据,应用程序崩溃,因为还没有从SharedPreferences中获取数据,并且应用程序在此之前加载。
其他参考文章:
多任务
dart笔记13:用future实现等待多个任务完成后,再得到所有的执行结果
1 | import 'dart:async'; |