號外:kitjs官方討論QQ群建立了,QQ群號88093625,歡迎大家加入,討論前端相關話題
今天給大家介紹一下kitJs的多線程類,以及原生的javascript,不藉助瀏覽器外掛程式以及HTML5的webWorker是如何?多線程模式的。
Demo地址:http://xueduany.github.com/KitJs/KitJs/index.html#multithread
(一)多線程簡單工作原理
所謂多線程,一般意義上理解,就是兩段程式塊,在作業系統的分時調配下,交錯運行。
1. 每個程式塊需要有自己獨立的線程運行環境以及獨立上下文
2. 每個程式塊包含多個語句塊,每個語句塊是原子的,不可分割的,例如while之類的迴圈
3. 語句塊和語句塊之間是可以分割執行的,以及支援sleep,比如a=1;b=2;這樣是兩個語句塊
4. 程式塊可以調用公用資源區,比如調用window空間下其他資源
5. 支援死迴圈解鎖,即殺死進程
(二)Kit是如何?的
首先我們通過$kit.multithread.newThread方法建立一個新的線程
newThread方法接受一個匿名函數,我們可以看到在這個匿名函數體內部,包含了獨立線程塊自己的資源,變數a/b,以及自己的邏輯
$kit.multithread.iterate方法提供一個迴圈方法,類似while,接受2個參數,參數1為一個是否執行迴圈的標記,參數2為一個迴圈體。
我們可以看到線程1的迴圈體的意思就是一個死迴圈,不斷的輸出“數字a為xxx”這樣的文字
在迴圈體內部,有一個sleep方法,是讓程式塊休眠指定的時間,這裡是100毫秒
線程2的意思就是b的遞減,輸出欄位,然後有兩個判斷,當b<995,kill線程1,當b<980時kill自己
最後就是線程定義完畢之後,執行方法
運行頁面,我們就會看到線程1和線程2交織執行
(三)原理解析
查看kit原始碼,我們可以看到
建立一個線程,kit會保留線程的id號以及線程對應的匿名方法
運行比較簡單,直接執行
延時的實現,使用setTimeout做延時,這裡有個技巧,在setTimeout裡面用匿名方法糾正this指標,同時線上程的附屬資訊裡面記錄延時執行的stack順序
迴圈的實現,最為複雜,可以看到首先保留遠程執行方法的上下文,定義一個inner Fn執行第一次方法體,然後用setInterval執行後續,在setInterval內部還要載入對於sleep的延時判斷,如果當前excuteStack處於sleep狀態,那麼繼續hold,等待sleep結束再繼續迴圈
殺死線程,清空所有的excuteStack裡面的timeout,delete線程註冊資訊
(四) 進階技巧
其實對於一個js程式塊來說,按照$kit提供的api改成這樣已經看上不去很不像一段簡單的js代碼了
如果要做的更友好一些,我們可以使用Regex做一個詞法分析器,通過fn.toString擷取function的代碼塊文本,分析,並轉換for語句,while語句成為$kit的iterate語句,直接轉換sleep(xxx);為$kit的sleep方法,這樣的代碼會寫的更友好一些,這裡只為拋磚引玉,歡迎有興趣的同學繼續改成$kit的多線程類,這裡也提供了一個parse方法,沒有實現