NativeScriptの利点の1つは、(非)直列化やリフレクションを使用せずに、JavaScriptを介してすべてのネイティブプラットフォーム(Android / Objective-C)APIにすばやく効率的にアクセスできることです。 ただし、これにはトレードオフがあります。すべてのJavaScriptはメインスレッド(AKA the UI thread)で実行されます。 つまり、時間がかかる可能性がある操作ではUIのレンダリングが遅れ、アプリケーションの外観が遅くなる可能性があります。
UIの鮮明さと高いパフォーマンスが重要な低速性の問題に取り組むために、開発者はネイティブスレッドのマルチスレッドワーカースレッドソリューションを使用できます。 ワーカーは、完全に分離されたコンテキストでバックグラウンドスレッドで実行されるスクリプトです。 実行に時間がかかる可能性があるタスクは、ワーカースレッドにオフロードする必要があります。
NativeScriptのWorkers APIは、Dedicated Web Workers APIとWeb Workers Specificationに大まかに基づいています。
new Worker(path)
- Workerのインスタンスを作成し、新しいOSスレッドを生成します。そこでは、pathパラメータが指すスクリプトが実行されます。postMessage(message)
- 関連するスクリプトのonmessageイベントハンドラにJSONシリアライズ可能なメッセージを送信します。terminate()
- 次の実行ループ時にワーカースレッドを終了します。ワーカーオブジェクトイベントハンドラ
onmessage(message)
- 関連付けられたワーカースレッドから送信された着信メッセージを処理します。メッセージオブジェクトには、以下のプロパティがあります。
message.data
- ワーカースレッドのpostMessageで送信されたメッセージの内容 onerror(error)
- ワーカースレッドからのキャッチされていないエラーを処理します。エラーオブジェクトからは以下のプロパティを取得できます。
error.message
- 捕捉されなかったエラー、および該当する場合はスタックトレースerror.filename
- 不明なエラーがスローされたファイルerror.lineno
- 不明なエラーがスローされた行self
- WorkerGlobalScope自身への参照を返しますpostMessage(message)
- メインスレッド上のWorkerインスタンスのonmessageイベントハンドラにJSONシリアライズ可能メッセージを送信します。close()
- 次の実行ループ時にワーカースレッドを終了しますワーカーグローバルスコープのイベントハンドラ
onmessage(message)
- メインスレッドから送信された着信メッセージを処理します。メッセージオブジェクトは以下のプロパティを公開します。
message.data
- メインスレッドのpostMessageで送信されたメッセージの内容onerror(error)
- ワーカースコープ(ワーカースレッド)内の関数の実行中に発生した不明なエラーを処理します。
errorパラメータには、不明なエラー(uncaught error)が含まれています。ハンドラーがtrueのような値を返すと、メッセージはメインスレッド上のワーカーインスタンスのonerrorハンドラーに伝搬されません。
ワーカースレッドのonerrorが呼ばれた後、ワーカーは実行を終了せず、メッセージを送受信できるようになります。onclose()
- 「クリーンアップ」作業を行います。リソースの解放、ストリームとソケットのクローズに適しています。main-view-model.js
...
const WorkerScript = require("nativescript-worker-loader!./worker-script.js");
const worker = new WorkerScript();
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
require('globals'); // necessary to bootstrap tns modules on the new thread
global.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 } : { }
global.postMessage(msg);
}
function processImage(src, mode, options) {
console.log(options); // will throw an exception if `globals` hasn't been imported before this call
// 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
// to handle errors implement the global.onerror handler:
// global.onerror = function(err) {}
ワーカープラグインの詳細については、nativescript-worker-loaderリポジトリを参照してください。
Workers APIを使用するときに最適な結果を得るには、以下のガイドラインに従ってください。
ワーカーで処理を行う際には、留意すべきいくつかの制限があります。
下記のプロジェクトは、Angular以外のNativeScriptプロジェクトおよびNativeScript Angularプロジェクトでマルチスレッド機能をどのように使用できるかを示しています。