前言

怎么将一个Callback回调转化成Future同步方法(Callback to Future),可以配套async / await去使用呢?

个人觉得,这是一个很常见的现象,不知道为啥,很多人在说明Future用法的时候,都没提到这个场景,奇怪+懵逼,只能自己去苟解决方案了。

实现

不多哔哔,先看实现,赶时间的靓仔,可以直接忽略掉历程描述

  • 记录下Callback to Future的写法,使用Completer类即可
class ViewUtil {
///界面初始化完成
static Future<Void> initFinish() async {
Completer<Void> completer = Completer(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
completer.complete();
}); return completer.future;
}
}
  • 使用

    • 使用起来,瞬间简单很多
void _init() async {
await ViewUtil.initFinish();
///下面可以使用加载弹窗
}

说明

  • Future和Completer的泛型最好保持一致

    • 例如都是String的话,complete()方法里面就可以加上相应的内容,然后await接受这个方法时候,就能拿到complete()方法里面输入的值了
class ViewUtil {
///界面初始化完成
static Future<String> initFinish() async {
Completer<String> completer = Completer(); WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
completer.complete("测试一下...");
}); return completer.future;
}
} void _init() async {
var s = await ViewUtil.initFinish();
print(s);
}

历程

  • 为什么我要将Callback转成Future方法?

    • 大家知道,Flutter在加载页面的时候,有个渲染的过程,在没渲染完成的时候,你去显示一些View的操作,会报错的,例如:加载loading弹窗
    • 解决方法可能大家都知道,Lifecycle.initState / iniState 生命周期里面做个延时操作或者使用WidgetsBinding
//延时操作
await Future.delayed(Duration(milliseconds: 200));
//下面可以加载弹窗 //使用WidgetsBinding
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
//此处可以加载弹窗
});
  • 当然,使用WidgetsBinding是更靠谱和准确的,但是这个Callback就让我很方了,而且,这名字太长,也不太记的住,这就需要将它封装了
  • 封装WidgetsBinding
    • 蛋筒了,这玩意怎么封装呢
class ViewUtil {
///界面初始化完成
static Future<Void> initFinish() async {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) { });
}
}
  • 首先我想到了:Future.delayed()

    • 进去看下他的源码
    • 有戏,可以看到,这里面明显包含了一个Timer中的Callback回调,但最后转换成了,Future方法
factory Future.delayed(Duration duration, [FutureOr<T> computation()?]) {
if (computation == null && !typeAcceptsNull<T>()) {
throw ArgumentError.value(
null, "computation", "The type parameter is not nullable");
}
_Future<T> result = new _Future<T>();
new Timer(duration, () {
if (computation == null) {
result._complete(null as T);
} else {
try {
result._complete(computation());
} catch (e, s) {
_completeWithErrorCallback(result, e, s);
}
}
});
return result;
}
  • 分析下

    • 首先是实例化一个_Future()对象,然后返回了这个_Future()对象
    • 可以看到方法的最下方是直接返回这个对象,可想而知,这地方,肯定一直处于一个阻塞状态,在等待一个条件结束这个阻塞状态
    • 然后在Timer的延迟时间到了后,其回调中使用了_complete()这个方法,这个方法应该是结束了_Future()对象的阻塞状态,然后再返回_Future()对象,同时这个方法也结束了
  • 这不就简单了,我把这个抄出来不就欧了

  • 这个_Future类是个私有方法,在future_impl.dart文件,把这个文件拷出来,放在我们工具类文件同一个包下,

    • 然后。。。

  • 这一堆报错,玩毛线啊,肯定是我打开的方式不对

    • 难道要一个一个去解决这些报错?要是这么麻烦,还搞毛线!

  • 是不是我搜索的姿势不对,再来搜搜看

    • 我去,还自动给我提示:dart callback to future,这么神奇的吗?试试看

Flutter&Dart Callback转同步的更多相关文章

  1. [flutter+dart] windows7下开发环境的安装与配置

    前言 博主是做嵌入式的,参加工作时间也不久,而且是非科班出身,之前从未接触过移动开发.最近了解到了flutter框架和dart语言,想作为第二语言学习一下,因此会从最基础的环节开始,以此博客作为记录, ...

  2. Android Gradle Issue - Flutter / Dart

    解决 "Minimum supported Gradle version is 4.6. Current version is 3.3." I have a problem wit ...

  3. Flutter & Dart

    Flutter & Dart https://www.dartlang.org/install https://flutter.dev/ https://flutter.dev/docs/ge ...

  4. 【Flutter 1-2】在 Windows 10下安装Flutter+Dart+Android Studio 配置Flutter开发环境

    在 Windows 10下安装Flutter+Dart+Android Studio 配置Flutter开发环境 文章首发地址 配置环境变量 由于部分网站被墙的原因,我们需要先配置Flutter国内镜 ...

  5. flutter & dart & vs code & bug

    flutter & dart & vs code & bug Waiting for another flutter command to release the startu ...

  6. 函数式编程:Flutter&Dart中的组合

    本文翻译自: Composition in Flutter & Dart 在 Flutter & Dart 中使用组合创建模块化应用程序. 什么是组合? 在dictionary.com ...

  7. flutter shared_preferences 异步变同步

    前言 在开发原生iOS或Native应用时,一般有判断上一次安装的版本和当前版本是否是同一个版本,如果不是同一个版本,则要显示引导页,这个过程是把版本号持久化存储起来,在每一次启动时进行判断,这个过程 ...

  8. Flutter & Dart 安装在window系统

    一.系统环境 flutter最低要求 1,windows7 SP1 64位版本以上,我的系统就是windows 7 sp1 64bit 2,git for windows ,没有安装的需要到这里下载  ...

  9. 将已经存在的异步请求callback转换为同步promise

    由于js是单线程执行,为防止阻塞,会有很多异步回调函数callback,嵌套层次多了,可读性就差了很多.随着社区的发展,出现了promise.我们来将一些常见的回调函数做修改,变成promise的链式 ...

  10. Flutter Dart中的异步

    以下内容从官网得到: https://webdev.dartlang.org/articles/performance/event-loop Even-Looper Dart是单线程模型,也就没有了所 ...

随机推荐

  1. LLM微调方法(Efficient-Tuning)六大主流方法:思路讲解&优缺点对比[P-tuning、Lora、Prefix tuing等]

    LLM微调方法(Efficient-Tuning)六大主流方法:思路讲解&优缺点对比[P-tuning.Lora.Prefix tuing等] 由于LLM参数量都是在亿级以上,少则数十亿,多则 ...

  2. 准入控制器(Admission Controller):ResourceQuota,ImagePolicyWebhook

    目录 一.系统环境 二.前言 三.准入控制器简介 四.为什么需要准入控制器 五.启用/禁用ResourceQuota资源配额 5.1 查看默认启用/禁用的准入控制器插件 5.2 ResourceQuo ...

  3. pytest执行_allure报“AttributeError: module 'allure' has no attribute 'severity_level'”

    背景: 一个大项目A,需要项目B作为源码,即pycharm的 source_root 问题: 项目B,执行pytest.main([pytest命令]),控制台报错"AttributeErr ...

  4. Linux 内核:sysfs 有关的API

    背景 相关文章:1.sysfs与kobject基类 下面内容基本上参考(有删改):https://blog.csdn.net/qb_2008/article/details/6846412 API a ...

  5. 【论文阅读】VDBFusion: Flexible and Efficient TSDF Integration of Range Sensor Data

    Type: Sensors Year: 2022 tag: Mapping 组织: Bonn 参考与前言 论文链接:https://www.ncbi.nlm.nih.gov/pmc/articles/ ...

  6. oeasy教您玩转python - 4 - # 调试程序

    ​ 调试程序 回忆上次内容 py 的程序都是写在明面上的 所有需要执行的事情都明着写到了 py 文件中 用 python3 解释 py 文件进行执行 可以下载人家写好的 py 文件 下载的 py 文件 ...

  7. MySQL 实现 EF Code First TimeStamp/RowVersion 并发控制

    在将项目迁移到MySQL 5.6.10数据库上时,遇到和迁移到PostgreSQL数据库相同的一个问题,就是TimeStamp/RowVersion并发控制类型在非Microsoft SQL Serv ...

  8. OpenGL book note

    OpenGL Shading language 4.0vertex shader geometry shader: 格式解释 https://blog.csdn.net/hankern/article ...

  9. 面试题-python 什么是装饰器(decorator )?

    前言 python装饰器本质上就是一个函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外的功能,装饰器的返回值也是一个函数对象.很多python初学者学到面向对象类和方法是一道大坎,那么py ...

  10. java引入es使用

    引入依赖 <dependency> <groupId>org.elasticsearch.client</groupId> <artifactId>el ...