黑科技:輕鬆實現JS與微信小程序中的多線程

前言

衆所周知,js是單線程的去跑代碼,如果使用一個較長時間的循環來執行代碼,瀏覽器就會卡死,直到js執行完畢,用戶體驗極差;因此對於較長時間的代碼塊,最好使用多線程去執行,關於這一點網上說可以用Dedicated Worker和Shared Worker來實現,在此不再贅述;

然而,在微信小程序中,也想用js實現多線程怎麼辦呢?API中爲我們提供了一個方法,多線程 Worker,然而,如圖所示:

worker只能創建一個,這也不行,那也不行;

關鍵是worker中不能使用wx對象,主js與worker通信只能通過參數傳遞的方式,然而參數只能是字符串json串之類的東西,不能傳遞對象與方法(本人親測),本來想使用wx創建一個對象然後傳遞給worker的,然而並不行,這就很難受。

總而言之,截止到2020.6.2,微信小程序的多線程方法限制太多,很難用。(js的多線程有些複雜,還沒試好不好用)

 

黑科技實現多線程

以下是本人實現多線程的方法,如果有大佬已經知道了,可以直接跳過。

1.核心方法:

//通常寫法
setTimeout(function(){alert("abc")}, 1000);
//另一種寫法
//setTimeout(function, milliseconds, param1, param2, ...)
function a(txt){
alert(txt);
}
setTimeout(a, 5000, "123");

2.setTimeout簡介

setTimeout可以設置一個延時執行的方法,可以傳入參數,可以傳入對象,可以通過對象執行方法;當延遲時間設置爲0時,基本就相當於多線程了,完全不會影響主線程的執行。

本人在微信小程序中遇到了不得不使用"多"線程的地方(那個worker是真的不能用,完全實現不了目的),找了半天,突然想到可以用setTimeout來實現多線程,迫不及待地嘗試了一下,雖然還比不上其它語言的專業的多線程,但是完全可以實現了本人的需求。

3.setTimeout多線程

需要給線程傳參數?直接傳給setTimeout中的方法就行了;

線程需要操作其它變量和方法?將其它變量和方法聲明成全局的就行了;

需要獲取線程返回值?用幾個全局變量,標一下線程id和參數內容就行了,當線程修改了id變量和內容變量時,主線程獲取就行了;

需要判斷線程是否執行完畢?再用幾個全局變量,當線程執行完畢後修改全局變量,然後主線程就能知道線程是否執行完畢了;

需要終止線程?setTimeout也可以實現,使用var t = setTimeout(...); 然後使用clearTimeout(t); 即可。

還有其它需求?嗯......本人暫時沒有了,但是感覺setTimeout基本都可以巧妙地實現。

4.setTimeout實現sleep方法

在js與微信小程序中,是沒有原生的sleep方法的;上文提到,js是單線程的去跑代碼,如果使用一個較長時間的循環來執行代碼,瀏覽器就會卡死,直到js執行完畢;有人利用這一點實現js的sleep方法,確實可以使得延遲一段時間後繼續執行下方的代碼,但是這期間瀏覽器是卡死狀態的,無法響應其它事件,用戶體驗很不好。

因此,使用setTimeout實現的sleep方法是比較方便的,只需要修改下代碼邏輯,讓後續代碼延遲指定時間後執行即可,在此期間頁面可以響應其它事件,比如用戶可以點擊按鈕來取消後續代碼的執行(而如果使用循環來延時執行後續代碼,瀏覽器是不會響應其餘事件的,很不靈活,而且頁面處於卡死狀態,用戶體驗極差)。

 

目前本人認爲setTimeout是JS和微信小程序中最好用的多線程方法了(至少實現了本人微信小程序中的需求)

 

總結

使用setTimeout可以在js與微信小程序中實現多線程,雖然可能不如其它語言中的多線程方法,不過本人感覺一般的多線程需求基本上都可以實現了;至於多線程共享數據需要加鎖之類的,本人還沒有研究過,不過感覺似乎也可以巧妙地實現。如果大家發現哪些地方setTimeout實現的多線程還不完美,歡迎下方留言討論;如果有更好的js與微信小程序中實現多線程的方法,也歡迎大家留言,謝謝!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章