持續發燒,試試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
的哭了,看家本領被人給偷了。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4369/viewspace-2797036/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 持續發燒,聊聊Dart語言的併發處理,能挑戰Go不?DartGo
- AndroidUtilCodeKTX !是時候提升你的開發效率了 !(持續更新中...)Android
- .net持續整合測試篇之Nunit that斷言
- 聊聊持續測試
- 持續測試效能的方法
- 聊聊持續測試的進階
- Linux 核心的持續整合測試Linux
- .net持續整合測試篇之Nunit常見斷言
- 提升龍蜥核心測試能力!探究持續性模糊測試最佳化實踐
- AI面試題(持續更新)AI面試題
- 聊聊持續測試與安全
- Hbase面試題(持續更新)面試題
- HTTP非持續連線和持續連線HTTP
- Flutter開發之Dart語言基礎FlutterDart
- 如何利用Requestly提升前端開發與測試的效率,讓你事半功倍?前端
- Dart語言概覽Dart
- dart語言基礎Dart
- 如何利用Allure報告提升你的測試效率?
- 跨境電商CRM必備:提升運營效率,實現持續盈利
- Spring面試題(持續更新中)Spring面試題
- 持續輸出面試題之Nginx面試題Nginx
- 【12】進大廠必須掌握的面試題-持續測試面試面試題
- .netcore持續整合測試篇之測試方法改造NetCore
- 介面效能測試 —— Jmeter併發與持續性壓測JMeter
- 【前端面試】Vue面試題總結(持續更新中)前端Vue面試題
- 前端面試問題二(持續更新)前端面試
- 持續交付會如何影響測試
- Vue.js 牛刀小試(持續更新~~~)Vue.js
- 使用 Xcode Server 持續整合 & 打包測試XCodeServer
- 持續輸出面試題之Hibernate篇面試題
- 持續輸出面試題之RocketMQ篇面試題MQ
- flutter【3】dart語言--方法FlutterDart
- Dart 語言入門 (四)Dart
- 提升軟體測試效率與靈活性:探索Mock測試的重要性Mock
- 【11】進大廠必須掌握的面試題-持續整合面試面試題
- 總結Java開發面試常問的問題,持續更新中~Java面試
- .net持續整合測試篇之Nunit引數化測試
- C語言的考試題型C語言