nsIObserverServiceを使って複数のobserverに通知を行う
FirefoxやThunderbirdの拡張を作る際に、場合によっては非同期処理が入ったりします。
XPCOMではそのような場面でobserverが簡単に仕込める仕組みとして、nsIObserverServiceと言うインターフェ−スがあるので、今回はその使い方についてご紹介します。
ObserverServiceの概要
そもそもnsIObserverServiceには下記のようなメソッドが定義されています。
- addObserver()
- removeObserver()
- notifyObservers()
- enumerateObservers()
以下簡単にそれぞれについて触れてみます。
- addObserver, removeObserver
- 特定のtopicに対して通知を受け取るobserverオブジェクトを設定したり消したり出来ます。
- notifyObservers()
- 特定のtopicを監視する全てのobserverに対して通知します
- enumerateObservers()
- 特定のtopicを監視するobserverをenumerationとして取得します。
observerの作り方
nsIObserverと言うインターフェースが存在しますので、その型を実装すれば問題無く使えます。
var testObserver = {
observe: function(subject, topic, data) {
if (topic != "testTopic") {
return;
}
repl.print(({
"subject": subject,
"topic": topic,
"data": data
}).toSource());
}
};
と言う訳でobserveメソッドを持つ適当なオブジェクトを上記のように作れば、後はnotifyがあればその通知を受け取る事が出来ます。
ちなみにMozRepl経由で確認すると楽に出来ます。
他の方法で見る方はalertなりerror consoleなりお好きな所に出力して下さい。
observerの登録
windowのload, unloadイベントでaddObserver(), removeObserver()を呼び出す処理を追記したobserverだと下記のようになります。
var testObserver = {
observerService: null,
init: function() {
testObserver.observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
testObserver.observerService.addObserver(testObserver, "testTopic", false);
},
observe: function(subject, topic, data) {
if (topic != "testTopic") {
return;
}
repl.print(({
"subject": subject,
"topic": topic,
"data": data
}).toSource());
},
complete: function() {
testObserver.observerService.removeObserver(testObserver, "testTopic");
}
};
testObserver.init, testObserver.completeは適当な場所で呼び出すようにしておきます。(例えばload, unloadイベントにaddEventListenerとして)
observalな処理の中でnotifyObserversを使う
例えばですが、長く掛かる処理と言うのをsetTimeoutで表現したとして、
var TestObserval = function() {
this.observerService = Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService);
}
TestObserval.prototype = {
observerService: null,
start: function() {
this.observerService.notifyObservers(null, "testTopic", "start");
setTimeout(this.process, 3000);
},
process: function() {
this.observerService.notifyObservers(null, "testTopic", "end");
}
}
としてあげて、オブジェクトを生成してstart()を実行してあげると、実際にnotifyが届いている事が分かると思います。
trackback
- trackback url
- trackback count
- 0
comment