Dart语法基础补充
Asynchrony support
Dart 库中充满了返回 Future 或 Stream 对象的函数。 这些函数是异步的:它们在设置一个可能耗时的操作(例如 I/O)后返回,而不等待该操作完成。
async 和 await 关键字支持异步编程,让编写看起来类似于同步代码的异步代码。
参考:Future class - dart:async library - Dart API
Stream class - dart:async library - Dart API
Handling Futures
需要已完成的 Future 的结果时,有两种选择:
- 使用异步和等待。
- 使用 Future API。
使用 async 和 await 的代码是异步的,但它看起来很像同步代码。 例如,下面是一些使用 await 等待异步函数结果的代码:
await lookUpVersion();
要使用 await,代码必须在异步函数中——标记为异步的函数:
Future<void> checkVersion() async {var version = await lookUpVersion();// Do something with version
}
注意:虽然异步函数可能会执行耗时的操作,但它不会等待这些操作。 相反,async 函数只会执行到它遇到第一个 await 表达式。 然后它返回一个 Future 对象,仅在 await 表达式完成后才恢复执行。
在使用 await 的代码中使用 try、catch 和 finally 来处理错误和清理:
try {version = await lookUpVersion();
} catch (e) {// React to inability to look up the version
}
可以在一个异步函数中多次使用 await。 例如,以下代码等待函数结果三次:
var entrypoint = await findEntryPoint();
var exitCode = await runExecutable(entrypoint, args);
await flushThenExit(exitCode);
在 await 表达式中,表达式的值通常是一个 Future; 如果不是,则该值会自动包装在 Future 中。 此 Future 对象指示返回对象的承诺。 await 表达式的值是返回的对象。 await 表达式使执行暂停,直到该对象可用。
void main() async {checkVersion();print('In main: version is ${await lookUpVersion()}');
}
注意:前面的示例使用异步函数 (checkVersion()) 而不等待结果——如果代码假定函数已完成执行,这种做法可能会导致问题。
Declaring async functions
异步函数是函数体标有 async 修饰符的函数。
将 async 关键字添加到函数使其返回 Future。 例如,考虑这个同步函数,它返回一个字符串:
String lookUpVersion() => '1.0.0';
把它改成一个异步函数——例如,因为Future的实现会很耗时——返回的值是一个Future:
Future<String> lookUpVersion() async => '1.0.0';
请注意,函数的主体不需要使用 Future API。 如果需要,Dart 会创建 Future 对象。 如果函数没有返回有用的值,请将其返回类型设置为 Future<void>。
Handling Streams
需要从Stream中获取值时,有两种选择:
- 使用异步和异步 for 循环(等待)。
- 使用 Stream API。
注意:在使用 await for 之前,请确保它使代码更清晰,并且确实想要等待Stream的所有结果。 例如,通常不应该为 UI 事件侦听器使用 await for,因为 UI 框架会发送无穷无尽的事件流。
异步 for 循环具有以下形式:
await for (varOrType identifier in expression) {// Executes each time the stream emits a value.
}
expression 的值必须具有 Stream 类型。 执行过程如下:
- 等到Stream发出一个值。
- 执行 for 循环的主体,并将变量设置为发出的值。
- 重复 1 和 2,直到Stream关闭。
要停止收听Stream,可以使用 break 或 return 语句,它会跳出 for 循环并取消订阅流。
如果在实现异步 for 循环时出现编译时错误,请确保 await for 位于异步函数中。 例如,要在应用程序的 main() 函数中使用异步 for 循环,必须将 main() 的主体标记为异步:
void main() async {// ...await for (final request in requestServer) {handleRequest(request);}// ...
}
异步编程参考:
Library tour | Dart
Generators
需要延迟生成一系列值时,请考虑使用生成器函数。 Dart 内置支持两种生成器函数:
- 同步生成器:返回一个 Iterable 对象。Iterable class - dart:core library - Dart API
- 异步生成器:返回一个 Stream 对象。https://api.dart.dev/stable/dart-async/Stream-class.html
实现一个同步生成器函数,将函数体标记为sync*,使用yield语句传递值:
Iterable<int> naturalsTo(int n) sync* {int k = 0;while (k < n) yield k++;
}
要实现异步生成器函数,将函数体标记为 async*,并使用 yield 语句传递值:
Stream<int> asynchronousNaturalsTo(int n) async* {int k = 0;while (k < n) yield k++;
}
如果你的生成器是递归的,你可以通过使用 yield* 来提高它的性能:
Iterable<int> naturalsDownFrom(int n) sync* {if (n > 0) {yield n;yield* naturalsDownFrom(n - 1);}
}
Callable classes
要允许 Dart 类的实例像函数一样被调用,请实现 call() 方法。
call() 方法允许任何定义它的类来模拟一个函数。 此方法支持与普通函数相同的功能,例如参数和返回类型。
class WannabeFunction {String call(String a, String b, String c) => '$a $b $c!';
}var wf = WannabeFunction();
var out = wf('Hi', 'there,', 'gang');void main() => print(out);Log
Hi there, gang!
Isolates
大多数计算机,甚至在移动平台上,都具有多核 CPU。 为了利用所有这些内核,开发人员传统上使用并发运行的共享内存线程。 然而,共享状态并发很容易出错,并可能导致代码复杂化。
所有 Dart 代码都运行在 isolates 中,而不是线程。 每个 Dart isolate 使用单个执行线程并且不与其他 isolate 共享可变对象。 旋转多个隔离创建多个执行线程。 这使得多线程没有其主要缺点,竞争条件。https://en.wikipedia.org/wiki/Race_condition#In_software
- Concurrency in Dart
- dart:isolate API reference, including Isolate.spawn() and TransferableTypedData
- Background parsing cookbook on the Flutter site
- Isolate sample app
Typedefs
类型别名——通常称为 typedef,因为它是用关键字 typedef 声明的——是一种引用类型的简洁方式。 下面是声明和使用名为 IntList 的类型别名的示例:
typedef IntList = List<int>;
IntList il = [1, 2, 3];
类型别名可以有类型参数:
typedef ListMapper<X> = Map<X, List<X>>;
Map<String, List<String>> m1 = {}; // Verbose.
ListMapper<String> m2 = {}; // Same thing but shorter and clearer.
在大多数情况下,建议对函数使用内联函数类型而不是 typedef。 但是,函数 typedef 仍然有用:
typedef Compare<T> = int Function(T a, T b);int sort(int a, int b) => a - b;void main() {assert(sort is Compare<int>); // True!
}
相关文章:
Dart语法基础补充
Asynchrony support Dart 库中充满了返回 Future 或 Stream 对象的函数。 这些函数是异步的:它们在设置一个可能耗时的操作(例如 I/O)后返回,而不等待该操作完成。 async 和 await 关键字支持异步编程,让编写看起来类…...
Nginx - 深入理解nginx的处理请求、进程关系和配置文件重载
概述 Nginx的系统学习整理的第三篇博客,主要介绍nginx的应用场景和架构基础,以便更好的理解,再生产环境中进行性能调优。 Nginx的三个主要应用场景 1.静态资源服务,通过本地文件系统提供服务 2.反向代理服务,强大的性…...
华为OD机试 - 服务依赖(Python)| 真题含思路
服务依赖 题目 在某系统中有众多服务,每个服务用字符串(只包含字母和数字,长度<=10)唯一标识,服务间可能有依赖关系,如A依赖B,则当 B 故障时导致 A 也故障。 传递具有依赖性,如 A依赖 B,B 依赖 C,当 C 故障时导致 B 故障,也导致 A 故障。给出所有依赖关系以及当…...
html的表单标签(form)
目录标题1、表单标签主要有三大类:2、表单标签中常见的属性3、例子代码及结果4、注意:5、表单中特殊的属性表单标签可以用来数据交互,而前面学的六个标签只能发送不能接收。 表单标签的作用就是数据交互1、表单标签主要有三大类: …...
手把手教你部署ruoyi前后端分离版本
下载源码(当前版本3.8.5)RuoYi-Vue: 🎉 基于SpringBoot,Spring Security,JWT,Vue & Element 的前后端分离权限管理系统,同时提供了 Vue3 的版本 (gitee.com)创建数据库(一定要是这三个&…...
JUC并发编程 Ⅱ -- 共享模型之管程(上)
文章目录共享带来的问题临界区 Critical Section竞态条件 Race Conditionsynchronized 解决方案synchronized语法解决方案思考面向对象改进方法上的 synchronized线程八锁变量的线程安全分析成员变量和静态变量是否线程安全?局部变量是否线程安全?局部变…...
File类
🏡个人主页 : 守夜人st 🚀系列专栏:Java …持续更新中敬请关注… 🙉博主简介:软件工程专业,在校学生,写博客是为了总结回顾一些所学知识点 ✈️推荐一款模拟面试,刷题神器…...
ModSecurity规则功能说明
ModSecurity规则功能说明 owasp规则: 第一部分:基础规则集 modsecurity_crs_20_protocol_violations.conf HTTP协议规范相关规则modsecurity_crs_21_protocol_anomalies.conf HTTP协议规范相关规则modsecurity_crs_23_request_limits.conf HTTP协议大小长度限制相…...
医学生考研考博太卷,一篇文章轻松助力上岸(一)
考研考博太卷了,卷不过,想没想过本科发一篇文章呢? 330分考研人淘汰390分考研人这个故事,大家应该都知道吧。 本专栏带你六个月内,搞定一篇文章,本科生发文章也很容易。 在卷考研的同时,再卷…...
操作系统(一): 进程和线程,进程的多种状态以及进程的调度算法
文章目录前言一、进程和线程1. 进程2. 线程二、进程和线程的区别(面试常问)三、进程调度算法3.1. 批处理系统3.2. 交互式系统3.2.1 时间片轮转3.2.2 优先级调度3.2.3 多级别反馈队列3.3. 实时系统四、进程的状态五、进程同步5.1 什么是进程同步5.2 进程同步应该遵循的几点原则前…...
【随笔】我迟到的2022年度总结:突破零粉丝,1个月涨粉1000+,2023年目标3万+
前言 我是21年12月注册的csdn, 作为用户平时看看文章,从未参与过写文章这件事。 但这一年的时间我见证了很多新号的崛起,有的号我平时关注比较多,看着他们从零粉丝突破了三万甚至五万的粉丝量。 在csdn上遇到了我的贵人&#x…...
SpringCloud-Netflix学习笔记13——Zuul路由网关
什么是Zuul? Zuul包含了对请求的路由和过滤两个最主要的功能。 其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础,而过滤器功能则负责对请求的处理过程进行干预,是实现请求校验,服务聚合等功能…...
Hive 之 DDL操作
DDL 操作是用于操作对象和对象的属性,这种对象包括数据库本身,以及数据库对象,像:表、视图等等 1. 数据库 1.1 创建数据库 数据库在 HDFS 上的默认存储路径是 /user/hive/warehouse/*.db CREATE (DATABASE|SCHEMA) [IF NOT EX…...
2. SpringMVC 请求与响应
文章目录1. 请求映射路径2. 请求参数2.1 get 请求发送普通参数2.2 post 请求发送普通参数2.3 五种类型的参数传递2.4.1 普通参数2.4.2 POJO 数据类型2.4.3 嵌套 POJO 类型参数2.4.4 数组类型参数2.4.5 集合类型参数3. json 数据传输参数(重点)3.1 传输 j…...
leaflet 读取上传的geojson文件,转换为wkt文件(057)
第057个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中上传geojson文件,解析geojson文件并转换为WKT,并在地图上显示图片。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果. 文章目录 示例效果配置方式示例源代码(共128行)安装 @terraf…...
面试题-前端开发Vue篇(答案超详细)
文章目录 如何实现跨域?JSONP原理和缺点谈谈你对DOM的理解及常用的DOM API说说你对 Vue 的理解说说 Vue 的优缺点什么是虚拟 DOM请描述下 vue 的生命周期是什么vue 如何监听键盘事件?watch 怎么深度监听对象变化删除数组用 delete 和 Vue.delete 有什么区别watch 和计算属性有…...
PTA甲级-1010 Radix c++
文章目录Input Specification:Output Specification:Sample Input 1:Sample Output 1:Sample Input 2:Sample Output 2:一、题干大意二、题解要点三、具体实现总结Given a…...
【项目重构】第1次思考
回顾与反思 2022年~至今(2023年2月),一共重构了2个项目。 第1个项目在重构的时候,总是想着把别人的代码copy过来,改一改,这就算重构好了。这样做效率太低,原因是前人写的代码不一定有很多注释…...
Java:SpringMVC的使用(2)
目录第十二章 REST风格CRUD练习12.1 搭建环境12.2 实现功能思路第十三章 SpringMVC消息转换器13.1 消息转换器概述13.2 使用消息转换器处理请求报文(1) 使用RequestBody获取请求体(2) 使用HttpEntity\<T>获取请求体及请求头13.3 使用消息转换器处理响应报文(1) 使用Respo…...
Elasticsearch7.8.0版本进阶——分布式集群(应对故障)
目录一、Elasticsearch集群的安装1.1、Elasticsearch集群的安装(win10环境)1.2、Elasticsearch集群的安装(linux环境)二、应对故障(win10环境集群演示)2.1、启动集群(三个节点)2.2、…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
C++实现分布式网络通信框架RPC(3)--rpc调用端
目录 一、前言 二、UserServiceRpc_Stub 三、 CallMethod方法的重写 头文件 实现 四、rpc调用端的调用 实现 五、 google::protobuf::RpcController *controller 头文件 实现 六、总结 一、前言 在前边的文章中,我们已经大致实现了rpc服务端的各项功能代…...
超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
Spark 之 入门讲解详细版(1)
1、简介 1.1 Spark简介 Spark是加州大学伯克利分校AMP实验室(Algorithms, Machines, and People Lab)开发通用内存并行计算框架。Spark在2013年6月进入Apache成为孵化项目,8个月后成为Apache顶级项目,速度之快足见过人之处&…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
Python:操作 Excel 折叠
💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...
在rocky linux 9.5上在线安装 docker
前面是指南,后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...
