Web Workers 是在HTML5中新增的,用來在web應用程序中實現後臺處理的一種技術。在HTML4中,js創建的程序都是單線程的,如果花費時間比較長的話web界面就會長時間沒有響應,最惡劣的情況還會跳出一個腳本提示框:“提示腳本運行時間過長,是否繼續?”於是就引出了Web Workers API。
在MapboxGL中爲了避免加載地圖數據時耗時太長導致阻塞,採用了Web Workers技術,在後臺創建了三個線程,耗時較長的工作都在後臺線程中完成。其核心是“webworkify”模塊,它是運行在node中的web workers模型,也是通過postMessage和onMessage實現線程間的通信。
在MapboxGL中用於完成對象間的通信的主要有三個對象:
Actor對象
Actor對象主要作用就是完成線程間的消息傳遞,主要包括三個函數:
1. receive()
2. send()
3. postMessage()
receive()函數主要處理從線程內發到主線程的消息,send()函數通過調用postMessage()發送消息。
Dispacher對象
Dispacher對象在主線程中,通過該對象向後臺線程發送消息,並在後天線程中進行處理。
Worker對象
Worker對象封裝了後臺線程的執行文件,其內部的代碼對瀏覽器而言是不可見的,相當於後臺。MapboxGL相關地圖數據的加載,圖標、註記等緩衝區的建立都是在後臺線程進行處理。通過Dispacher對象向Worker對象發送消息,worker對象根據消息類型進行相應的處理。在worker對象內部,通過Actor對象發送消息與主線程進行通信。
例如,在worker對象內部通過發送一個“debug”類型的消息:
this.actor.send('debug',tile.data);
在Actor對象的receive()函數中添加該類型消息的處理函數:
if (data.type === '<response>'){ //如果是響應消息,表明子線程已處理完成,執行回調函數
callback = this.callbacks[data.id];
delete this.callbacks[data.id];
callback(data.error || null, data.data);
} else if (data.type === 'debug'){//從子線程傳回的調試消息
console.log("以下爲調試消息:");
console.log(data.data);
console.log("調試結束");
}
這樣就可以調試從後臺線程傳回的變量,執行後在控制檯就可以看到以下消息: