一、简介

Postal.js是一种受AMQP启发、用JavaScript编写的内存消息总线,可以运行在浏览器端或node.js服务端。它使用熟悉的事件触发模式,并通过提供代理和订阅者实现更复杂的事件触发(聚合)来扩展此模式。

二、用法

1、订阅

如果你想订阅一个消息,你可以告诉postal需要监听的频道(channel)和主题(topic),还有一个消息送达时的回调函数,其中channel是可选的,如果没有指定channel,postal会提供一个默认的channel。

var subscription = postal.subscribe({
	channel: "orders",
	topic: "item.add",
	callback: function(data, envelope) {
		//do something
	}
});

回调函数中,data是发布者发送的数据,envelope是对数据的包装,包含以下类容:

  • 消息的元数据,类似:频道(channel)、主题(topic)

  • 时间戳和其他可能已经存在的数据

  • 由发送者添加的数据

2、发布

发布者需要做类似以下的事情:

postal.publish({
	channel: "orders",
	topic: "item.add",
	data: {
		sku: "AZDTF4346",
		qty: 21
	}
});

3、样例

<script src="./js/lodash.js"></script>
<script src="./js/postal.js"></script>

  • 更简洁的写法

获取ChannelDefinition实例,然后使用该实例的subscribe方法订阅、使用publish方法发布,这实际上是一个在特定频道上订阅和发布的便利包装。

var channel = postal.channel("orders");
var subscription = channel.subscribe("item.add", function(data, envelope){
	//do something
});
channel.publish("item.add", {
	sku: "AZDTF4346",
	qty: 21 
});

  • 取消订阅
subscription.unsubscribe();

4、通配符

  • *

*表示主题中的一个单词(例如:主题中两个句号之间的文本),如果订阅的是*.changed,则会匹配name.changedlocation.changed,而不会匹配changed.companion

var channel = postal.channel("testing");
var subscription = channel.subscribe("*.changed", function(data, envelope){
	//do something
	console.log(data);
});
channel.publish("name.changed", {
	name: 'albert'
});
channel.publish("location.changed", {
	location: 'BeiJing'
});
channel.publish("changed.companion", {
	data: 'xxx'
});
subscription.unsubscribe();

  • #

#表示主题字符串中的0~n个字符或单词,如果订阅的是DrWho.#.Changed,则会匹配DrWho.ChangedDrWho.Location.ChangedDrWho.NinthDoctor.Companion.Changed,而不会匹配Changed

var channel = postal.channel("testing");
var subscription = channel.subscribe("DrWho.#.Changed", function(data, envelope){
	//do something
	console.log(data);
});
channel.publish("DrWho.Changed", {
	name: 'albert'
});
channel.publish("DrWho.Location.Changed", {
	location: 'BeiJing'
});
channel.publish("DrWho.NinthDoctor.Companion.Changed", {
	data: 'companion'
});
channel.publish("Changed", {
	data: 'xxx'
});
subscription.unsubscribe();

5、distinctUntilChanged()

在订阅时使用此方法,当发布多次时如果数据未发生变化,则只触发一次订阅回调函数。

  • 不使用distinctUntilChanged
var dupChannel = postal.channel( "Blink" );
var dupSubscription = dupChannel.subscribe( "WeepingAngel.#", function( data ) {
	console.log(data);
});
dupChannel.publish( "WeepingAngel.DontBlink", { value:"Don't Blink" } );
dupChannel.publish( "WeepingAngel.DontBlink", { value:"Don't Blink" } );

  • 使用distinctUntilChanged
var dupChannel = postal.channel( "Blink" );
var dupSubscription = dupChannel.subscribe( "WeepingAngel.#", function( data ) {
	console.log(data);
}).distinctUntilChanged();
dupChannel.publish( "WeepingAngel.DontBlink", { value:"Don't Blink" } );
dupChannel.publish( "WeepingAngel.DontBlink", { value:"Don't Blink" } );
dupChannel.publish( "WeepingAngel.DontEvenBlink", { value:"Don't Even Blink" } );
dupChannel.publish( "WeepingAngel.DontBlink", { value:"Don't Close Your Eyes" } );
dupSubscription.unsubscribe();

附:

postal - npm