單位來新人,慣例要先學三個月的莫爾斯報,因爲訓練軟件是是十年前用MFC開發的,沒法修改功能,且不兼容win7,常常有錯誤閃退,因此我寫了一個簡易的練習系統。從設計到完成一共用了七天左右時間,具有隨機生成、考覈、聽寫、翻譯和中文譯解功能,並能夠控制報文類型,數量,速度,能夠設置背景音樂和聲音強度。css
源碼下載地址:https://github.com/gusuziyi/morse-train.gitnode
圖一:主界面jquery
圖二:支持五種報文webpack
圖三:隨機生成20組字碼git
圖四:點擊聽寫,會按照設定速度發報,並能夠設置背景雜音和雜音強度es6
圖五:翻譯功能,目前支持中文,大寫英文,小寫英文以及各類符號github
圖六:點擊紅色按鈕,進行翻譯web
圖七:翻譯功能支持不一樣語言,大小寫和各類符號同時輸入gulp
圖八:翻譯出的結果支持聽寫,發報時相應的元素會標紅,就不會看串行了~bootstrap
圖九:反譯功能可以把莫斯碼反譯成可理解的報文
API
均位於morse.js當中
Getmorse:(line9)用於生成各種型莫爾斯碼,目前支持長碼、短碼、字碼、混合碼、勤務用語五種,可根據須要自行擴充
InitBtn:(line70)用於爲頁面中全部按鈕賦予功能
goTranslate:(line221)翻譯模塊,首先判斷是否有中文,無中文,使用混合碼字典,有中文,則調用xmorse模塊
artiTranslate:(line259)反譯模塊,判斷是否只有 . 和 – 的莫爾斯碼,是則反譯成報文,不是則翻譯成莫爾斯碼
playBg:(line279)播放選定的背景音樂
closeBg:(line289)終止選定的背景音樂
async play:(line296)用於處理系統產生的 點、劃、字、詞等事件,決定如何播放和等待
playAudio:(line322)區分點、划進行播放調度
sleep:(line342)系統休眠,用於生成聽寫時的時間間隙
createTranslate:(line349)將翻譯出的報文轉譯成系統可播放、識別的格式。思路是字符串轉數組,數組元素包裹span插入dom,以實現跟隨聽寫字符標紅,摩斯碼打碎成點劃並加入byte、word等控制信息
createMessage:(line419)隨機生成若干組報文,實現思路同上
initWidget:(line480)初始化widget,注意不要在widget內再封裝widget,沒有內部通訊方法
playDot:(line532)爲正弦波添加矩形濾波器後調製,在440hz上0.1秒內聲音近似爲點
playLine:(line567)同上,只是將包絡時長設置爲dot的三倍
總結:
1、關於gulp,因爲以前一直在學webpack,因此常常看到webpack和gulp相比較的文章,正好此次有這個需求,就嘗試了一下gulp,使用體驗就是很簡單,用了二小時看了幾篇文章就很熟練了,固然缺點也是簡單,一些事情作不到,還有一些事情要用額外插件來作,配置起來很麻煩。好比這個程序裏絕大部分使用es5語法,有一些[…]、promise、require之類的es6語法,還有await、async這種es7語法,而瀏覽器只認識es5,這就致使必須用babel轉碼,而babel在gulp須要手工配置,這是一個天坑。首先babel-core和 gulp-babel版本不能用最新的,會報錯誤找不到@babelcore,至少要退化兩個以上的版本
圖十:我使用的babel-core 和 gulp-babel版本
其次要支持es7,必須添加babel-plugin-transform-runtime,同時在.babelrc文件中添加對應的plugins
圖十一:支持es7 asyns的配置
你覺得這就完了?transform-runtime會把regenerator轉換成require,只是把es7轉成了es6,能夠在node上運行,可是想要用script直接引用還要添加gulp-browserify轉成es5,注意順序,要在babel()以後,在uglity()以前
圖十二:gulp-browserify的配置
二 關於jQueryUi框架,頁面使用了jQueryUi,也沒多想,就是想試試沒用過的東西,嚐嚐鮮,在菜鳥教程看了幾篇文章大概半天上手,在思路上它是對dom元素進行widget初始化的方式來表現ui,可是這些widget屏蔽了外部通訊事件,不容易找到解決方案,好比這個軟件中,一開始我把背景雜音和背景強度封裝在一個controlGroup當中,結果select的onchange事件竟然失效了!震驚,後來不得不用css實現了controlGroup的樣式。這個地方若是不熟悉的話坑會不少,因此我感受沒有bootstrap+jquery效率高,jQueryUi對我來講應該是淺嘗輒止,之後不會再用了。
圖十三:jQueryUi的初始化十分簡單易懂
圖十四:select的change事件
三 關於異步低速函數,之前在node裏就是無限的回調函數嵌套,在es7中有了await和async這兩個方法。
await和async就相似於回調嵌套,但聲明他們的時候不會執行,如圖十五和圖十六中,tempI和play全是async函數,他們把任務不斷細分,函數執行是在圖十七和圖十八中的playAudio和sleep函數,他們兩個都是play中的分支任務,當他們返回new Promise時會執行自身。在內存中定義本身,而當setTimeOut運行以後返回的resolve會結束await狀態,父函數play會繼續執行,從而能夠實現使用setTimeOut節拍來控制發報速度
圖十五:tempI
圖十六:tempI的子函數play
圖十七:play的子函數playAudio
圖十八:play的子函數sleep
圖十九:gulp正確運行
最後,關於使用開關取消promise鏈,控制播放與中止的思路:爲開關添加isOn屬性,點擊時能控制isOn在true和false之間切換,而後在async play中監聽此屬性,若關閉,則拋出錯誤,如圖二十一,而後在其父函數中catch這個錯誤,打印錯誤,如圖二十。該方法的核心就是在子函數中監聽全局變量,而後拋出錯誤給父函數進行處理。
圖二十:使用try-catch運行異步函數
圖二十一:子函數play中監聽點擊事件,拋出錯誤