# [**多線程模式**](http://docs.nativescript.org/core-concepts/multithreading-model#multithreading-model)
NativeScript的好處之一就是它允許通過JS快速高效地使用所有原生平臺( Android\/Objective-C )的API,而不用使用串行化或者映射。然而這導致另一個糾結——所有JS都在主線程上執行 \(又名: `UI thread`\) 。這意味著操作很可能花掉很多時間停滯于UI渲染并且讓應用看起來感覺很慢。
要解決UI的清晰度和高性能帶來的緩慢是至關重要的,開發者可以使用 NativeScript的解決方案處理多線程——工作者線程。工作者是在一個絕對隔離的上下文中在后臺線程上執行的腳本。要花掉很多時間執行的任務應該卸裝到一個工作者線程之上。
NativeScript 里的 Workers API 是松散地基于 [Dedicated Web Workers API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers) 和 [Web Workers Specification](https://www.w3.org/TR/workers/) 。
* [Workers API](http://docs.nativescript.org/core-concepts/multithreading-model#workers-api)
* [Worker Object](http://docs.nativescript.org/core-concepts/multithreading-model#worker-object-prototype)
* [Worker Global Scope](http://docs.nativescript.org/core-concepts/multithreading-model#worker-global-scope)
* [Sample Usage](http://docs.nativescript.org/core-concepts/multithreading-model#sample-usage)
* [Limitations](http://docs.nativescript.org/core-concepts/multithreading-model#limitations)
## [**Workers API**](http://docs.nativescript.org/core-concepts/multithreading-model#workers-api)
### **[Worker 對象原型](http://docs.nativescript.org/core-concepts/multithreading-model#worker-object-prototype)**
* `new Worker(path)` - 創建一個worker的一個實例,并生成一個操作系統的新線程,該腳本的指向由執行的 `path` 參數決定。
* `postMessage(message)` - 發送一個串行化的JSON消息關聯腳本的 `onmessage` 事件處理器。
* `terminate()` - 終止運行下一個運行循環上的worker線程。
**Worker** 對象事件處理器
* `onmessage(message)` - 處理發送自關聯的worker線程傳入的消息。消息對象有如下屬性:
* `message.data` - 消息內容, 如在worker線程發送的 `postMessage` 。
* `onerror(error)` - 處理從worker線程未捕獲的錯誤。. 錯誤對象暴露如下屬性:
* `error.message` - 未發現的錯誤,一個堆棧,如果可用的話。
* `error.filename` - 文件位置,如果拋出未捕獲錯誤的話。
`error.lineno` - 行號,如果拋出未捕獲錯誤的話。
### **[Worker 全局范圍 ](http://docs.nativescript.org/core-concepts/multithreading-model#worker-global-scope)**
* `self` - 返回 `WorkerGlobalScope` 本身的一個引用。
* `postMessage(message)` - 發送一個串行化的JSON消息到主線程上的Worker 實例的 `onmessage` 事件處理器。
* `close()` - 終止運行下一個運行循環上的worker線程。
**Worker 全局范圍事件處理器**
* `onmessage(message)` - 處理發送自主r線程傳入的消息。消息對象暴露如下屬性:
* `message.data` - 消息內容, 如在主r線程發送的 `postMessage` 。
* `onerror(error)` - 處理 Worker 作用域(worker線程)內部執行的函數未捕獲的錯誤 。 `error` 參數包含未捕獲的錯誤。如果處理器返回一個真類的值,消息不會傳播到主線程上的 Worker 實例的 `onerror` 處理器。`onerror` 調用 worker 線程之后,執行不會被終止,worker仍然能夠發送\/接收消息。
* `onclose()` - 處理任何“清理”工作;適用于釋放資源,關閉流和套接字。

> **main-view-model.js **
>
> ---
>
> `...`
>
> `var worker = new Worker('./workers/image-processor');`
>
> `worker.postMessage({ src: imageSource, mode: 'scale', options: options });`
>
> `worker.onmessage = function(msg) {`
>
> `if (msg.data.success) {`
>
> `// Stop idle animation`
>
> `// Update Image View`
>
> `// Terminate worker or send another message`
>
> `worker.terminate();`
>
> `} else {`
>
> `// Stop idle animation`
>
> `// Display meaningful message`
>
> `// Terminate worker or send message with different parameters`
>
> `}`
>
> `}`
>
> `worker.onerror = function(err) {`
>
> ``console.log(`An unhandled error occurred in worker: ${err.filename}, line: ${err.lineno} :`);``
>
> `console.log(err.message);`
>
> `}`
>
> `...`
>
> **workers\/image-processor.js **
>
> ---
>
> `onmessage = function(msg) {`
>
> `var request = msg.data;`
>
> `var src = request.src;`
>
> `var mode = request.mode || 'noop' ;`
>
> `var options = request.options;`
>
> `var result = processImage(src, mode, options);`
>
> `var msg = result !== undefined ? { success: true, src: result } : { }`
>
> `postMessage(msg);`
>
> `}`
>
> `function processImage(src, mode, options) {`
>
> `// image processing logic`
>
> `// save image, retrieve location`
>
> `// return source to processed image`
>
> `return updatedImgSrc;`
>
> `}`
>
> ``// does not handle errors with an `onerror` handler``
>
> `// errors will propagate directly to the main thread Worker instance`
## [**General Guidelines**](http://docs.nativescript.org/core-concepts/multithreading-model#general-guidelines)通用指導原則
為了最理想的結果,當使用 Workers API 時,請遵循這些準則:
* 當 worker結束任務時,使用適合的API \(`terminate()` 或`close()`\) ,始終要確保關閉 worker 線程。如果在你工作的作用域之內,你的 Worker 實例在你能終止它之前變得不能得到,你要關閉它,就只能在worker自身的腳本里通過調用 `close()` 函數。
* Workers 不是所有性能相關問題的通用解決方案。 開啟一個Worker 有它自身的開銷, 而且它可能有時會比處理一個快速任務更慢。所以,在訴諸worker之前優化數據庫請求,或重新考慮復雜應用邏輯。
* 線程可以訪問整個原生SDK, 當 調用API時 ,nativescript 開發者必須照顧到所有的同步,這些從多個線程的調用無法保證線程安全。
## **[Limitations限制](http://docs.nativescript.org/core-concepts/multithreading-model#limitations)**
當使用 worker時有一些限制要記住:
* 不存在JS共享內存。這意味著你不能從任一線程獲得JS的值\/對象。你只能串行化對象,把它發送到另一個線程并在那里反串行化。這就是 postMessage\(\) 函數所負責的。然而,原生對象沒有這個情況。你可以從多個線程獲取一個原生對象,而不用復制它,因為 runtime 將創建每個線程單獨的JavaScript包裝對象。請記住,當您使用非線程安全的原生API和數據時,你必須自己處理同步部分。 runtime 在原生數據訪問和API調用上,不執行任何鎖定或者同步邏輯。
* 只有串行化JSON 對象可以被 postMessage\(\) API 發送。
* 你不能發送原生對象。意思是你不能通過 postMessage 發送原生對象,因為在大多數情況下,JSON序列化JavaScript包裝一個原生對象的結果為空的-“{ }” 字面的對象。另一方面這個消息會被反序列化到一個純粹的空的JavaScript對象。發送原生對象是我們希望在未來支持的,所以敬請關注。
* 此外,當發送循環對象時要小心,因為它們的遞歸節點將在序列化步驟中剝離。
* 沒有對象傳輸。如果你是一個Web開發者你可能熟悉ArrayBuffer和MessagePort的傳輸在瀏覽器被支持。目前, NativeScript 沒有這種對象傳輸的概念。
* 目前,你無法調試運行在worker線程的上下文中的腳本。以后會實現。
* 沒有嵌套的worker支持。我們希望從社區獲知如果這在一定程度上需要我們支持的話。