ProtoViewLogic: messageHandler()

post() / broadcast() によって送られたメッセージを処理します。

開発者は派生クラスでメッセージを処理するためにこの関数をオーバーライドする必要があります。

この関数は非同期関数です。

構文

protoViewLogic.messageHandler(msg) => Promise<boolean>

引数

  • msg: object

    この関数を呼び出した呼び出し元のメソッド post() または broadcast() から渡されるメッセージオブジェクトです。このメッセージオブジェクトには呼び出し元のメソッドによってプロパティ targetdeliver が追加されています。

    • id: string | null

      メッセージの識別子です。

      addActiveEvents() で有効にしたイベント通知に対しては、イベント発生した要素への参照を持つプロパティ名が設定されます。

    • code: string | null

      メッセージの追加の識別子です。

      addActiveEvents() で有効にしたイベント通知に対しては、発生したイベントの種別が設定されます。

    • param: any

      メッセージが持つパラメータです。DOM要素から受け取ったイベントなど、何らかの値の受け渡しに利用します。

    • origin: any

      メッセージの送信元です。

    • target : ProtoViewLogic

      メッセージの直接の送信先の ProtoViewLogic です。

    • deliver: function

      単一のオブジェクトを受け取り boolean または Promise<boolean> を返します。

      引数のオブジェクトはプロパティとしてメッセージ処理を行う関数を持ちます。 deliver() の呼び出しに際し、idcode の値に応じて引数のオブジェクトのプロパティに設定された関数が実行されます。

返値: Promise<boolean>

メッセージが処理されたなら true, 未処理なら false を返すプロミスです。

解説

このコールバックは post() / broadcast() の呼び出しの中で実行されます。

ユーザは自身が実装する ProtoViewLogic 派生クラスの中でこの関数をオーバライドしなければなりません。オーバーライドしなかった場合、その ProtoViewLogic は自身ではメッセージ処理を行いません。

対象の ProtoViewLogic がメッセージ処理を行わなかった場合、メッセージ処理を移譲します。移譲先は呼び出し元によって異なります。

  • post() の場合、親の ProtoViewLogic にメッセージ処理を移譲します。
  • broadcast() の場合、子の ProtoViewLogic にメッセージ処理を移譲します。

メッセージの処理は引数 msg を介して行います。

直接 msg.idmsg.code に対して if 文や switch 文で分岐を表現することもできますが、ヘルパ関数 msg.deliver() によっても msg.id および msg.code による分岐を表現できます。

ヘルパ関数 msg.deliver() は副作用を持ちます。

一回目の呼び出しでは引数 handlerMap から msg.id にキーが一致する関数を呼び出します。ただし、msg.id が指定されなかった場合、代わりに msg.code に一致するキーを探し、msg.code も指定されなかった場合、代わりに固定の文字列 "default" に一致するキーを探します。

msg.deliver()msg.id に一致する関数を探し、その呼び出しに成功した場合、次の msg.deliver() の呼び出しでは msg.code に一致する関数を引数 handlerMap から探します。

同様に、msg.deliver()msg.code に一致する関数を探し、その呼び出しに成功した場合、次の msg.deliver() の呼び出しでは msg.id に一致する関数を引数 handlerMap から探します。

つまり、msg.deliver() の呼び出しは交代的に msg.idmsg.code をキーとして使用します。

msg.idmsg.code"default" のいずれにも一致する関数が存在しなかった場合、msg.deliver() はメッセージ未処理として false を返します。

msg.deliver() によるメッセージ処理の流れです。

stateDiagram-v2 deliver(id) : msg.deliver(handlerMap) find_id : Search msg.id for handlerMap call_id : handlerMap\[msg.id\](msg) deliver(code) : msg.deliver(handlerMap) find_code : Search msg.code for handlerMap call_code : handlerMap\[msg.code\](msg) find_default : Search "default" for handlerMap call_default : handlerMap\["default"\](msg) state process_id <> state process_code <> %%state call_default <> state process_default <> [*] --> deliver(id) deliver(id) --> find_id find_id --> call_id : Found find_id --> find_code : Not found call_id --> process_id : Success to call call_id --> False : Failed to call process_id --> True process_id --> False process_id --> deliver(code) : Process msg.code deliver(code) --> find_code True --> [*] False --> [*] find_code --> call_code : Found find_code --> find_default : Not found call_code --> process_code : Success to call call_code --> False : Failed to call process_code --> True process_code --> False process_code --> deliver(id) : Process msg.id find_default --> call_default : Found find_default --> False : Not found call_default --> process_default : Success to call call_default --> False : Failed to call process_default --> True process_default --> False

deliver() を利用する場合、引数 handlerMapmsg を引数とし boolean を返す関数をプロパティに持つオブジェクトでなければなりません。もし handlerMap が持つ関数が boolean 以外の値を返した場合、それは常に true として扱われます。

messageHandler() の返値は post() / broadcast() にとってメッセージが処理されたかどうかを判断するための値となります。msg.deliver() と同様、messageHandler()boolean 以外の値を返した場合、それは常に true として扱われます。

理由がない限り deliver() の返値と messageHandler() の返値は一致するよう実装すべきです。

msg.deliver() の引数 handlerMap を定義する際には注意を払う必要があります。handlerMap のプロパティの値をアロー関数にした場合、その中における this はアロー関数を定義したレキシカルスコープによって定まります。一方、通常の関数にした場合、thishandlerMap 自身となるよう deliver() 内で扱われます。

handlerMap のプロパティとして、Function.prototype.bind()this が指定された関数が渡された場合にも同様の注意が必要です。この場合、bind() で指定されたオブジェクトが this に設定され、これは一般には handlerMap 自身とは異なります。