ProtoViewLogic: broadcast()
対象の ProtoViewLogic インスタンスの子孫へ同一メッセージを送ります。
この関数は非同期関数です。
構文
protoViewLogic.broadcast(message) => Promise<boolean>
引数
-
message:object送信するメッセージです。 このオブジェクトは以下のプロパティを持ちます:
-
id:string|nullメッセージの識別子です。
-
code:string|nullメッセージの追加の識別子です。
-
param:any|nullメッセージが持つパラメータです。
-
origin:object|nullメッセージの生成元です。
-
返値: Promise<boolean>
送信したメッセージが消費されたかどうかを解決時に示すプロミスです。
true として解決された場合、メッセージが消費されたことを示し、false なら消費されなかったことを示します。
例外
TypeError- 引数
messageが非nullのオブジェクトでなかった場合。
- 引数
AggregateError- 子孫がメッセージ処理に失敗した場合。
broadcast()内で生じた例外をプロパティerrors: Error[]として持ちます。
- 子孫がメッセージ処理に失敗した場合。
例
import { ProtoViewLogic } from "/alier_sys/ProtoViewLogic.js";
import { ViewLogic } from "/alier_sys/ProtoViewLogic.js";
import { AlierView } from "/alier_sys/AlierView.js";
const vlParent = new ProtoViewLogic;
const pl = new class Polish extends ProtoViewLogic {
async messageHandler(message) {
message.deliver({
greet: message => {
console.log(`message.id = ${message.id}, message.code = ${message.code}: Witaj!`);
}
});
}
};
const laHost = new AlierView();
// AlierView に取り付けるためこれは派生クラスの ViewLogic を使う
const la = new class Latin extends ProtoViewLogic {
async messageHandler(message) {
message.deliver({
saluto: message => {
console.log(`message.id = ${message.id}, message.code = ${message.code}: Salvete!`);
}
});
}
};
laHost.attach(la);
const en = new class English extends ProtoViewLogic {
async messageHandler(message) {
message.deliver({
greet: message => {
console.log(`message.id = ${message.id}, message.code = ${message.code}: Welcome!`);
}
});
}
};
const jp = new class Japanese extends ProtoViewLogic {
async messageHandler(message) {
message.deliver({
aisatsu: message => {
console.log(`message.id = ${message.id}, message.code = ${message.code}: いらっしゃい!`);
}
});
}
};
// 事前準備: 親子関係を作る
vlParent.relateViewLogics({ en, pl });
en.relateViewLogics({ jp });
pl.relateElements({ laHost });
// これは以下の木構造を作る:
// vlParent --- en --- jp
// `- pl ... la
console.group("broadcast: id = greet");
await vlParent.broadcast(vlParent.message("greet", null, null));
// => 以下のログが表示される:
// "message.id = greet, message.code = default: Welcome!"
// "message.id = greet, message.code = default: Witaj!"
console.groupEnd();
console.group("broadcast: id = aisatsu");
await vlParent.broadcast(vlParent.message("aisatsu", null, null));
// => 以下のログが表示される:
// "message.id = aisatsu, message.code = default: いらっしゃい!"
console.group("broadcast: id = saluto");
await vlParent.broadcast(vlParent.message("saluto", null, null));
// => 以下のログが表示される:
// "message.id = saluto, message.code = default: Salvete!"
console.groupEnd();
解説
メッセージ処理は直接の子から行われます。もしメッセージが未消費の子があれば、未消費だった子からその子孫へ送られます。
ここで「子孫」とは、relateViewLogics() によって関連付けられた直接の子孫の ProtoViewLogic に加えて、relateElements() によって関連付けられた Element の logic プロパティを介して参照される、実質的な子孫の ProtoViewLogic を含めます。
実質的な子孫には例えば、AlierView に attach() 関数によって取り付けられた ViewLogic が該当します。
メッセージ処理では post() と同様に messageHandler() が呼び出されます。
ただし post() と異なり、親や祖先へのメッセージ伝播は行われません。つまり、broadcast() したメッセージは「逆流」しません。
messageHandler() の中で何らかの例外が発生した場合、例外を発生させた ProtoViewLogic の子孫へはメッセージが送られません(メッセージは 消費された と見なされる)。
その他の子孫に対するメッセージ処理と伝播は引き続き行われますが、broadcast() の呼び出し自体は呼び出し中に発生した例外をまとめた AggregateError を発生させます。