前言

昨天发了篇文章《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. Kibana探索数据(Discover)

    总结说明: 1.先在Management/Kibana/Index Patterns 界面下添加索引模式(前提是有索引数据) 2.在Discover界面选中响应的索引模式 3.开启Kibana 查询语 ...

  2. Ubuntu20.04和Docker环境下安装Redash中文版

    创建Ubunt20.04虚拟机,请参考:https://www.linuxidc.com/Linux/2020-03/162547.htm 一.安装基础环境: # 1.更换APT国内源 sudo se ...

  3. 实用脚本:检查高 CPU / 内存消耗进程

    1 检查高 CPU 消耗进程在 Linux 上运行了多长时间的 Bash 脚本 该脚本将帮助你确定高 CPU 消耗进程在 Linux 上运行了多长时间. # vi /opt/scripts/long- ...

  4. SpringBoot的starter到底是什么?

    前言 我们都知道,Spring的功能非常强大,但也有些弊端.比如:我们需要手动去配置大量的参数,没有默认值,需要我们管理大量的jar包和它们的依赖. 为了提升Spring项目的开发效率,简化一些配置, ...

  5. androidmanifest.xml 反编译

    androidmanifest.xml 反编译 去除更新只修改androidmanifest.xml内容 解压apk文件后得到这个文件androidmanifest.xml windwos安装java ...

  6. Django 之ModelAdmin对象

    一.后台管理系统配置 1 在该表对应的models类里面添加一个Meta类 class Meta: verbose_name_plural = '用户表' #指定该表在admin后台的名字为:用户表  ...

  7. ClickHouse(07)ClickHouse数据库引擎解析

    目录 Atomic 建表语句 特性 Table UUID RENAME TABLES DROP/DETACH TABLES EXCHANGE TABLES ReplicatedMergeTree in ...

  8. 可观测性的常见用例|Techtarget

    [ 文章来源 ]https://www.techtarget.com/searchitoperations/tip/Common-use-cases-for-observability 这些可观测性用 ...

  9. Oracle注入

    Oracle 查询出所有的表 select * from all_tables 查询出当前用户的表 select * from user_tables 查询出所有的字段 select*from all ...

  10. 强国杯东杯分区赛miscwp

    ​ 目录 不要被迷惑 PCAP文件分析 平正开 不要被迷惑 ​编辑 导出http ​编辑 得到flag.zip后直接爆破密码 ​编辑 得到​编辑 然后一键解码 ​编辑 flag{WImuJeqSNPh ...