持续发烧,试试Dart语言的异步操作,效率提升500%
前言
昨天发了篇文章《Dart开发服务端,我是不是发烧(骚)了》,承蒙小编看得起上了首页。
今天持续发烧,再来写写如何使用 Dart
语言的异步操作。说起异步操作,玩 NodeJS
的同学会心一笑,这就是我们的看家本领啊。玩 PHP
, JAVA
的同学也就看看,表示我们光看不说话。
代码演示之前,我们先假设一个场景。假设我有一些漂亮妹妹,我别出心裁的想发电子邮件给他们,表达爱心。在这里个过程中,代码需要做的事情:
- 接收请求
- 保存我的邮件内容到数据库
- 还需要把邮件内容发送到她们的邮箱。
- 返回结果
这个过程中,我关心的是发一封邮件需要多长时间,因为我妹妹太多了,一封邮件的时间太长的话,我就没办法照顾到其他人了。那上面4个步骤里,哪些步骤会耗时呢?
很显然,1 和 4 基本绝对不耗时,2 需要点时间,但是时间很短,3 需要的时间最长,因为涉及到网络传输,不可控因素太多。
同步代码是什么样的
我们先用同步代码的方式来模拟上面的流程。
假设保存信息到数据库需要 1
秒,发送邮件到对方邮箱需要 5
秒,总体应该是 6
点多。
import 'dart:io';
main() {
acceptRequest(); //接受请求
saveToDb(); //保存到数据库,不太耗时, 假设需要1秒
sendLetter(); //发送邮件到对方邮箱,非常耗时, 假设需要5秒
returnRes(); //返回结果
}
void acceptRequest() {
print(DateTime.now().toString() + ' 接受请求');
}
void saveToDb() {
sleep(Duration(seconds: 1));
print(DateTime.now().toString() + ' 保存数据库成功');
}
void sendLetter() {
sleep(Duration(seconds: 5));
print(DateTime.now().toString() + ' 发送邮件成功');
}
void returnRes() {
print(DateTime.now().toString() + ' 返回结果');
}
执行它,得到打印的结果
2021-06-29 16:40:44.993785 接受请求
2021-06-29 16:40:46.000240 保存数据库成功
2021-06-29 16:40:51.002400 发送邮件成功
2021-06-29 16:40:51.002400 返回结果
简单计算一下,从接受请求到返回结果,总共耗时 6
秒左右,符合预期。
异步代码又是什么样子
刚才说了,我有好多漂亮妹妹,则一封邮件都要那么长时间,那么多妹妹得多长时间啊,能不能快点呢?
当然可以了,代码如下:
main() async {
acceptRequest(); //接受请求
await saveToDb(); //保存到数据库,不太耗时, 需要1秒
sendLetter(); //发送邮件到对方邮箱,非常耗时, 需要5秒
returnRes(); //返回结果
}
void acceptRequest() {
print(DateTime.now().toString() + ' 接受请求');
}
void saveToDb() async {
await Future.delayed(Duration(seconds: 1));
print(DateTime.now().toString() + ' 保存数据库成功');
}
void sendLetter() async {
await Future.delayed(Duration(seconds: 5));
print(DateTime.now().toString() + ' 发送邮件成功');
}
void returnRes() {
print(DateTime.now().toString() + ' 返回结果');
}
执行它,得到打印结果
2021-06-29 16:47:46.931323 接受请求
2021-06-29 16:47:47.956545 保存数据库成功
2021-06-29 16:47:47.959539 返回结果
2021-06-29 16:47:52.960542 发送邮件成功
这个结果,可需要注意看了。有两点需要特别注意:
- 从接收请求到返回结果,总共消耗了1秒左右
- 发送邮件成功,竟然出现在返回结果得后面,间隔5秒
为什么是这样? 实际上这就是 Dart
语言异步操作得魅力所在。
Dart
默认情况下是按照代码顺序来执行任务。
但是当执行到 sendLetter
得时候,发现它是一个 async
异步的操作,并且暂时不用等待它,然后就直接跳过他,执行了后面 returnRes
,因此打印出了 返回结果
返回结果之后,如果是浏览器请求的话,那么这个浏览器请求就直接结束了。但是事情并没有结束,Dart
继续执行了刚刚跳过的 sendLetter
, 所以最后打印出了 发送邮件成功
整体下来,我这次发邮件,只用了 1
秒钟,而之前是 6
秒啊,这个效率提升,足足有 500%
嗯嗯,真是太棒了,可以照顾到更多妹妹了。
await async 究竟是个啥
眼尖的同学估计看出来了,上面的代码中
main() async {
acceptRequest(); //接受请求
await saveToDb(); //保存到数据库,不太耗时, 需要1秒
sendLetter(); //发送邮件到对方邮箱,非常耗时, 需要5秒
returnRes(); //返回结果
}
saveToDb
保存数据库 与 sendLetter
发送油价都是耗时操作,为什么 saveToDb
前面加了 await
?
这是因为, saveToDb
也是异步操作,如果不加 await
,它就会像 sendLetter
发送邮件一样,先被跳过,浏览器返回结果后,才被执行。这样会产生一个问题,如果写入数据库失败了,但是你已经告诉用户成功了,这不尴尬了吗?
所以, saveToDb
前面加了 await
, 告诉 Dart
这段代码虽然是异步的,你要同步执行。
总结
当一个操作非常耗时的话,我们就可以将其设置成异步 async
,先给用户返回信息,再慢慢处理。
如果想把某异步操作变为同步的话, 可以加关键字 await
, 表示我愿意等待这个异步结果。
Dart
提供了异步操作的机制,我们可以很方便的来使用他们。
玩 NodeJS
的哭了,看家本领被人给偷了。
持续发烧,试试Dart语言的异步操作,效率提升500%的更多相关文章
- Dart语言入门(一)
Dart 语言介绍 Dart 是谷歌在 2011 年推出的编程语言,是一种结构化 Web 编程语言,允许用户通过 Chromium 中所整合的虚拟机(Dart VM)直接运行 Dart 语言编写的程序 ...
- Dart语言特性必备了解!
学习Dart语言,必须将以下的概念熟记于心: 在dart语言中,一切皆为对象.所有的对象都是一个类的实例.甚至整数.函数.null也看做是对象.所有的对象都继承于Object类 尽管Dart是强类型语 ...
- 30分钟掌握Dart语言
在Dart中,一切都是对象,一切对象都是class的实例,哪怕是数字类型.方法甚至null都是对象,所有的对象都是继承自Object 虽然Dart是强类型语言,但变量类型是可选的因为Dart可以自动推 ...
- Atitit.dart语言的特性 编译时js语言大总结
Atitit.dart语言的特性 编译时js语言大总结 1. 原型环境1 1.1. Dart可以编译js3 2. 第二个期待的理由是Dart的语言特性,没有什么特别特性好像,类似java c#一小时 ...
- Fluter基础巩固之Dart语言详解<一>
在上一篇https://www.cnblogs.com/webor2006/p/11367345.html中咱们已经搭建好了Flutter的开发环境了,而Flutter的开发语言是选用的dart,那么 ...
- Dart 语言简述
Dart是一种“结构化的web编程”语言,Dart编程语言在所有现代浏览器和环境中提供高性能.Dart是谷歌开发的计算机编程语言,后来被ECMA认定为标准. Dart重要的概念: 1.所有的东西都是对 ...
- Dart 语言简易教程系列
google Fuchsia系统 及 dart语言简介 在 InteIIiJ IDEA 中搭建 Dart 的开发环境 Dart Linux 开发环境搭建 Dart 语言简易教程(一) Dart 语言简 ...
- Dart语言快速学习上手(新手上路)
Dart语言快速学习上手(新手上路) // 声明返回值 int add(int a, int b) { return a + b; } // 不声明返回值 add2(int a, int b) { r ...
- 红黑树的删除详解与思路分析——不同于教科书上的算法(dart语言实现)
对于红黑树的删除,看了数据结构的书,也看了很多网上的讲解和实现,但都不满意.很多讲解都是囫囵吞枣,知其然,不知其所以然,讲的晦涩难懂. 红黑树是平衡二叉树的一种,其删除算法是比较复杂的,因为删除后还要 ...
- Dart 语言了解
Dart 语言了解 概念 当您了解Dart语言时,请记住以下事实和概念: 您可以放在变量中的所有内容都是一个对象,每个对象都是一个类的实例.偶数,函数和 null对象.所有对象都从Object类继承. ...
随机推荐
- Kibana探索数据(Discover)
总结说明: 1.先在Management/Kibana/Index Patterns 界面下添加索引模式(前提是有索引数据) 2.在Discover界面选中响应的索引模式 3.开启Kibana 查询语 ...
- Ubuntu20.04和Docker环境下安装Redash中文版
创建Ubunt20.04虚拟机,请参考:https://www.linuxidc.com/Linux/2020-03/162547.htm 一.安装基础环境: # 1.更换APT国内源 sudo se ...
- 实用脚本:检查高 CPU / 内存消耗进程
1 检查高 CPU 消耗进程在 Linux 上运行了多长时间的 Bash 脚本 该脚本将帮助你确定高 CPU 消耗进程在 Linux 上运行了多长时间. # vi /opt/scripts/long- ...
- SpringBoot的starter到底是什么?
前言 我们都知道,Spring的功能非常强大,但也有些弊端.比如:我们需要手动去配置大量的参数,没有默认值,需要我们管理大量的jar包和它们的依赖. 为了提升Spring项目的开发效率,简化一些配置, ...
- androidmanifest.xml 反编译
androidmanifest.xml 反编译 去除更新只修改androidmanifest.xml内容 解压apk文件后得到这个文件androidmanifest.xml windwos安装java ...
- Django 之ModelAdmin对象
一.后台管理系统配置 1 在该表对应的models类里面添加一个Meta类 class Meta: verbose_name_plural = '用户表' #指定该表在admin后台的名字为:用户表 ...
- ClickHouse(07)ClickHouse数据库引擎解析
目录 Atomic 建表语句 特性 Table UUID RENAME TABLES DROP/DETACH TABLES EXCHANGE TABLES ReplicatedMergeTree in ...
- 可观测性的常见用例|Techtarget
[ 文章来源 ]https://www.techtarget.com/searchitoperations/tip/Common-use-cases-for-observability 这些可观测性用 ...
- Oracle注入
Oracle 查询出所有的表 select * from all_tables 查询出当前用户的表 select * from user_tables 查询出所有的字段 select*from all ...
- 强国杯东杯分区赛miscwp
目录 不要被迷惑 PCAP文件分析 平正开 不要被迷惑 编辑 导出http 编辑 得到flag.zip后直接爆破密码 编辑 得到编辑 然后一键解码 编辑 flag{WImuJeqSNPh ...