Skip to content
uupaa edited this page May 11, 2016 · 23 revisions

Namespace

Entity of Postal module is located in the global.WebModule.Postal.
If you want publish to global namespace.

Postal モジュールの実体は、global.WebModule.Postal にあります。
global 名前空間に直接公開する事もできます。その場合は global.Postal でもアクセス可能になります。

API

Postal.prototype.register

Postal#register(receiver:ReceiverObject):this は、メッセージを受信するレシーバーオブジェクトを登録し、IDを割り振ります。

receiver は inbox メソッドを持っている必要があります。

var receiverObject = {
        inbox: function(message) { // message -> "Hello"
            return true;
        }
    };

var postal = new Postal();

postal.register(receiverObject);
postal.to().send("Hello");
postal.unregister(receiverObject);
function ReceiverClass() { }
ReceiverClass.prototype.inbox = function(message) {};

var receiverObject = {
        inbox: function(message) {}
    };

var postal = new Postal();

postal.register( new ReceiverClass() ); // 登録できます
postal.register( receiverObject );      // 登録できます
postal.register( {} );                  // 登録できません(inboxメソッドが無いためエラーになります)

Postal.prototype.unregister

Postal#unregister(receiver:ReceiverObject):this は、登録済みのレシーバーオブジェクトを抹消します。

Postal.prototype.unregisterAll

Postal#unregisterAll():this は、登録済みの全てのレシーバーオブジェクトを抹消します。

Postal.prototype.id

Postal#id(receiver:ReceiverObject):String は、Postal#register で設定されたレシーバーオブジェクトのIDを返します。

返される値は1から始まる数字文字列です。

var receiverObject = {
        inbox: function(message) { // message -> "Hello"
            return true;
        }
    };

var postal = new Postal();

postal.register(receiverObject);
postal.id(receiverObject) // -> "1"

Postal.prototype.to

Postal#to(receiver = null):Envelope は、receiver をメッセージの宛先とした Envelope(封筒)オブジェクトを生成し返します。宛先を追加します。

Postal#to と Postal#remove を組み合わせて Envelope に宛先を追加/削除していきます。

var foo = { inbox: function() {} };
var bar = { inbox: function() {} };
var buz = { inbox: function() {} };
var postal = new Postal();

postal.register(foo).register(bar).register(buz);

このように、foo, bar, buz の3つが登録されている状態で、

  • postal.to()foobarbuz を宛先に設定した Envelope オブジェクトを返します。ブロードキャスト(一斉通知)が可能な状態になります
  • postal.to(foo)foo だけを宛先に設定した Envelope オブジェクトを返します
  • postal.to(foo).to(bar)foobar を宛先に設定した Envelope オブジェクトを返します
  • postal.to(foo).to(bar).to(buz)postal.to() と一緒です
  • postal.to().to(foo)postal.to() と一緒です。foo が二重に宛先に登録される事はありません

Postal.prototype.remove

Postal#remove(receiver):Envelope は、Envelope オブジェクトから receiver を削除し Envelope オブジェクトを返します。宛先を削ります。

var foo = { inbox: function() {} };
var bar = { inbox: function() {} };
var buz = { inbox: function() {} };
var postal = new Postal();

postal.register(foo).register(bar).register(buz);

このように、foo, bar, buz の3つが登録されている状態で、

  • postal.remove(foo)postal.to().remove(foo) と同じです。foo が除外され、bar, buz を宛先に設定した Envelope オブジェクトを返します
  • postal.remove(foo).remove(bar)foo, bar が除外され、buz を宛先に設定した Envelope オブジェクトを返します
  • postal.to(foo).remove(foo) は宛先が空のEnvelope オブジェクトを返します。このメッセージはどこにも届かなくなります
function Foo() { }

Foo.prototype.inbox = function(msg, arg1, arg2) {
    console.log("Foo#inbox", arg1, arg2);
    return true;
};

function Bar() { }

Bar.prototype.inbox = function(msg, arg1, arg2) {
    console.log("Bar#inbox", arg1, arg2);
    return true;
};

function Buz() { }

Buz.prototype.inbox = function(msg, arg1, arg2) {
    console.log("Buz#inbox", arg1, arg2);
    return true;
};

var foo = new Foo();
var bar = new Bar();
var buz = new Bar();
var postal = new Postal();

postal.register(foo).register(bar).register(buz);

postal.to().send("hello");                // foo, bar, buz にメッセージが届きます
postal.to(foo).to(bar).send("hello");     // foo, bar にメッセージが届きます
postal.remove(bar).send("hello");         // foo, buz にメッセージが届きます
postal.to().remove(bar).send("hello");    // foo, buz にメッセージが届きます
postal.to(bar).remove(bar).send("hello"); // どこにもメッセージは届きません

envelope.send

envelope.send(message:String, param:Any...):Object はメッセージの同期送信を行い、envelope に設定された receiver の inbox メソッドを呼び出し、inbox メソッドの戻り値を格納したオブジェクトを返します。

envelope.send は同期送信で、envelope.post は非同期送信です。
envelope に複数の宛先が設定されている場合は、順番にメッセージを送信します。

  • envelope.send と envelope.post には複数のパラメタを渡す事ができます
    • パラメタは、inbox(message, param...) の形で渡されます
  • envelope.send はinboxの実行結果を返します
  • envelope.post はinboxの実行結果を返しません。常に{}を返します。

envelope.send() の戻り値から receiver.inbox() メソッドの戻り値を特定するには、まず Postal#id(receiver) で receiver のID を求め、次にそのIDを使い envelope.send() の戻り値を検索します。

var foo = {
        inbox: function(message, param1, param2) {
            return param1 + param2;
        }
    };
var bar = {
        inbox: function(message, param1, param2) {
            return param1 * param2;
        }
    };

var postal = new Postal().register(foo).register(bar);
var envelope = postal.to();

// foo.inbox と bar.inbox にメッセージ"calc"を送信します
// resultObject に戻り値が2つ格納されます
//      foo.inbox("calc", 2, 4) -> 6 (2+4)
//      bar.inbox("calc", 2, 4) -> 8 (2*4)

var resultObject = envelope.send("calc", 2, 4); // -> { "1": 6, "2": 8 }
var foo_id = postal.id(foo); // -> "1"
var bar_id = postal.id(bad); // -> "2"

console.log( resultObject[ foo_id ] ); // -> 6
console.log( resultObject[ bar_id ] ); // -> 8

Envelope.post

Envelope.post(message:String, param:Any...):Object はメッセージの非同期送信を行い、Envelope に設定された receiver の inbox メソッドを呼び出します。戻り値は空のオブジェクトです(inboxメソッドの戻り値はどこにも格納されません)

Envelope.first

envelope.first(message:String, param:Any...):Any|undefined はメッセージの同期送信を行い、envelope に設定された receiver の inbox メソッドを呼び出し、inbox メソッドの戻り値を返します。有効な戻り値が無い場合は undefined を返します。

receiver が複数存在する場合は、Array#some とよく似た(要素を順番に評価し true を返すとループアウトする)動作を行います。

  1. 最初の receiver.inbox を呼び出します
  2. inbox の戻り値を評価します。null または undefined 以外なら、その値を返して処理を終了します
  3. 次の receiver があるなら**5.**に移動します。無い場合は undefined を返して処理を終了します
  4. 次の receiver.inbox を呼び出します
  5. 2. に移動します
var foo = {
        inbox: function(message, param1, param2) {
            return param1 + param2;
        }
    };
var bar = {
        inbox: function(message, param1, param2) {
            return param1 * param2;
        }
    };

var postal = new Postal().register(foo).register(bar);
var envelope = postal.to(foo).to(bar);

envelope.send("calc", 2, 4); // -> foo.inbox("calc", 2, 4) -> return (2 + 4) -> 6

Postal.prototype.send

Postal#send() は postal.to().send() のショートカットです。Postal#register で登録済みの全ての receiver.inbox を呼び出し、全ての receiver.inbox の実行結果を格納した Object { "receiver-id": resultValue ,... } を返します。

var foo = {
        inbox: function(message, param1, param2) {
            return param1 + param2;
        }
    };
var bar = {
        inbox: function(message, param1, param2) {
            return param1 * param2;
        }
    };

var postal = new Postal().register(foo).register(bar);

var resultObject = postal.send("hello", 1, 2); // foo.inbox("hello"), bar.inbox("hello") を呼び出します
var emptyObject  = postal.post("hello", 2, 3); // foo.inbox("hello"), bar.inbox("hello") を呼び出します

Postal.prototype.post

Postal#post() は postal.to().post() のショートカットです。Postal#register で登録済みの全ての receiver.inbox を呼び出します。

Postal.prototype.first

Postal#first(message:String, param:Any...):Any|undefined は postal.to().first() のショートカットです。Postal#register で登録済みの全ての receiver.inbox を順番に呼び出し有効な戻り値を得られた時点で処理を終了し、inbox の戻り値を返します。

有効な戻り値が得られない場合は undefined を返します。

// この例では foo.inbox は呼ばれますが、bar.inbox は呼ばれません

var foo = {
        inbox: function(message, param1, param2) {
            return param1 + param2;
        }
    };
var bar = {
        inbox: function(message, param1, param2) {
            return param1 * param2;
        }
    };

var postal = new Postal().register(foo).register(bar);
var result = postal.first("calc", 2, 4); // -> foo.inbox("calc", 2, 4) -> return (2 + 4) -> 6

console.log(result) // -> 6