前言

昨天发了篇文章《Dart开发服务端,我是不是发烧(骚)了》,承蒙小编看得起上了首页。

今天持续发烧,再来写写如何使用 Dart 语言的异步操作。说起异步操作,玩 NodeJS 的同学会心一笑,这就是我们的看家本领啊。玩 PHP, JAVA 的同学也就看看,表示我们光看不说话。

代码演示之前,我们先假设一个场景。假设我有一些漂亮妹妹,我别出心裁的想发电子邮件给他们,表达爱心。在这里个过程中,代码需要做的事情:

  1. 接收请求
  2. 保存我的邮件内容到数据库
  3. 还需要把邮件内容发送到她们的邮箱。
  4. 返回结果

这个过程中,我关心的是发一封邮件需要多长时间,因为我妹妹太多了,一封邮件的时间太长的话,我就没办法照顾到其他人了。那上面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. 从接收请求到返回结果,总共消耗了1秒左右
  2. 发送邮件成功,竟然出现在返回结果得后面,间隔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%的更多相关文章

  1. Dart语言入门(一)

    Dart 语言介绍 Dart 是谷歌在 2011 年推出的编程语言,是一种结构化 Web 编程语言,允许用户通过 Chromium 中所整合的虚拟机(Dart VM)直接运行 Dart 语言编写的程序 ...

  2. Dart语言特性必备了解!

    学习Dart语言,必须将以下的概念熟记于心: 在dart语言中,一切皆为对象.所有的对象都是一个类的实例.甚至整数.函数.null也看做是对象.所有的对象都继承于Object类 尽管Dart是强类型语 ...

  3. 30分钟掌握Dart语言

    在Dart中,一切都是对象,一切对象都是class的实例,哪怕是数字类型.方法甚至null都是对象,所有的对象都是继承自Object 虽然Dart是强类型语言,但变量类型是可选的因为Dart可以自动推 ...

  4. Atitit.dart语言的特性  编译时js语言大总结

    Atitit.dart语言的特性  编译时js语言大总结 1. 原型环境1 1.1. Dart可以编译js3 2. 第二个期待的理由是Dart的语言特性,没有什么特别特性好像,类似java c#一小时 ...

  5. Fluter基础巩固之Dart语言详解<一>

    在上一篇https://www.cnblogs.com/webor2006/p/11367345.html中咱们已经搭建好了Flutter的开发环境了,而Flutter的开发语言是选用的dart,那么 ...

  6. Dart 语言简述

    Dart是一种“结构化的web编程”语言,Dart编程语言在所有现代浏览器和环境中提供高性能.Dart是谷歌开发的计算机编程语言,后来被ECMA认定为标准. Dart重要的概念: 1.所有的东西都是对 ...

  7. Dart 语言简易教程系列

    google Fuchsia系统 及 dart语言简介 在 InteIIiJ IDEA 中搭建 Dart 的开发环境 Dart Linux 开发环境搭建 Dart 语言简易教程(一) Dart 语言简 ...

  8. Dart语言快速学习上手(新手上路)

    Dart语言快速学习上手(新手上路) // 声明返回值 int add(int a, int b) { return a + b; } // 不声明返回值 add2(int a, int b) { r ...

  9. 红黑树的删除详解与思路分析——不同于教科书上的算法(dart语言实现)

    对于红黑树的删除,看了数据结构的书,也看了很多网上的讲解和实现,但都不满意.很多讲解都是囫囵吞枣,知其然,不知其所以然,讲的晦涩难懂. 红黑树是平衡二叉树的一种,其删除算法是比较复杂的,因为删除后还要 ...

  10. Dart 语言了解

    Dart 语言了解 概念 当您了解Dart语言时,请记住以下事实和概念: 您可以放在变量中的所有内容都是一个对象,每个对象都是一个类的实例.偶数,函数和 null对象.所有对象都从Object类继承. ...

随机推荐

  1. Ant Design槽位失效

    保证数据结构中有scopedSlots: { title: 'title' }, 即包含scopedSlots属性 使用时名字应保证一致 例如: 数据结构: treeData: [  {    key ...

  2. 洛谷P2627 [USACO11OPEN]Mowing the Lawn G (单调队列优化DP)

    一道单调队列优化DP的入门题. f[i]表示到第i头牛时获得的最大效率. 状态转移方程:f[i]=max(f[j-1]-sum[j])+sum[i] ,i-k<=j<=i.j的意义表示断点 ...

  3. SpringSecurity 在 SSM架构中的使用

    SpringSecurity - SSM SpringSecurity 对比 Shiro SpringSecurity的特点: 能和 Spring无缝贴合 能实现全面的权限控制 专门为 Web开发而设 ...

  4. 代码随想录第二天| 977.有序数组的平方 ,209.长度最小的子数组 ,59.螺旋矩阵II

    2022/09/22 第二天 第一题 这题我就直接平方后排序了,很无脑但很快乐啊(官方题解是双指针 第二题 滑动窗口的问题,本来我也是直接暴力求解发现在leetCode上超时,看了官方题解,也是第一次 ...

  5. 批量查询hive库中所有表的count

    一.准备文件 mkdir /query_hive_table_count touch query_db_name_table touch query_table_result.txt 二.编辑文件 2 ...

  6. lnmp配置laravel访问环境报错锦集

    1.laravel配置域名访问变成下载,实际就是Nginx没有识别到.php文件.把.php文件的配置加到Nginx即可 .... # 这一段放到项目的Nginx.conf配置文件里面 locatio ...

  7. 线性表的基本操作(C语言实现)

    文章目录 这里使用的工具是DEV C++ 可以借鉴一下 实现效果 顺序存储代码实现 链式存储存储实现 这里使用的工具是DEV C++ 可以借鉴一下 一.实训名称 线性表的基本操作 二.实训目的 1.掌 ...

  8. C#设置picturebox滚动条来实现查看大图片

    要给PictureBox添加滚动条需要以下步骤:    (1)将picturebox放在panel上:   ( 2)将panel的AutoScroll设置为ture:    (3)将picturebo ...

  9. 大数据下一代变革之必研究数据湖技术Hudi原理实战双管齐下-上

    @ 目录 概述 定义 发展历史 特性 使用场景 编译安装 编译环境 编译Hudi 关键概念 TimeLine(时间轴) File Layouts(文件布局) 索引 表类型 查询类型 概述 定义 Apa ...

  10. # Android网络请求(4) 网络请求框架Volley

    Android网络请求(4) 网络请求框架Volley Volley是Google在2013年5月15日到17日在旧金山Moscone中心举办网络开发者年会中推出的Android异步网络加载框架和图片 ...