持續發燒,試試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
- 聊聊持續測試
- .net持續整合測試篇之Nunit that斷言
- 聊聊持續測試的進階
- .net持續整合測試篇之Nunit常見斷言
- 聊聊持續測試與安全
- Linux 核心的持續整合測試Linux
- AndroidUtilCodeKTX !是時候提升你的開發效率了 !(持續更新中...)Android
- Laravel 持續測試主控平臺Laravel
- 持續測試企業架構架構
- 如何利用Requestly提升前端開發與測試的效率,讓你事半功倍?前端
- HTTP非持續連線和持續連線HTTP
- 如何利用Allure報告提升你的測試效率?
- 跨境電商CRM必備:提升運營效率,實現持續盈利
- 介面效能測試 —— Jmeter併發與持續性壓測JMeter
- Vue.js 牛刀小試(持續更新~~~)Vue.js
- 軟體測試持續整合的方法實踐
- 軟體測試過程的持續改進
- .net持續整合測試篇之Nunit引數化測試
- .netcore持續整合測試篇之測試方法改造NetCore
- 提升軟體測試效率與靈活性:探索Mock測試的重要性Mock
- Flutter開發之Dart語言基礎FlutterDart
- 持續整合之路——資料訪問層的單元測試(續)
- 使用 Xcode Server 持續整合 & 打包測試XCodeServer
- Dart語言概覽Dart
- dart語言基礎Dart
- SoapUI實踐:自動化測試、壓力測試、持續整合UI
- C語言的考試題型C語言
- 持續測試跟自動化測試的這些區別你知道嗎?
- 簡單談一下我對持續測試下的測試左移、迭代測試和測試右移的理解吧
- 功能測試怎麼提升測試開發能力?
- flutter【3】dart語言--方法FlutterDart
- Dart 語言入門 (四)Dart
- WinRT開發語言的功能和效率薦
- 在持續測試中使用哪種測試?談談DevOps在測試策略中的實踐!dev
- 提升測試效率,為需要軟體測試報告的企業節約時間成本測試報告
- 加速Java應用開發速度3:單元/整合測試+持續整合Java
- C語言單元測試C語言