From cc608044f58e9fbb0ecae146af3646e962d1233e Mon Sep 17 00:00:00 2001 From: Jim Cowart Date: Tue, 13 Sep 2011 23:13:53 -0400 Subject: [PATCH] Updating README.MD with examples --- README.md | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 135 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index eba2422..403d427 100644 --- a/README.md +++ b/README.md @@ -16,29 +16,156 @@ Why, yes. There are great alternatives to Postal. If you need something leaner ## How do I use it? In a nutshell, Postal provides an in-memory message bus, where clients subscribe to a topic (which can include wildcards, as we'll see), and publishers publish messages (passing a topic along with it). Postal's "bindingResolver" handles matching a published message's topic to subscribers who should be notified of the message. When a client subscribes, they pass a callback that should be invoked whenever a message comes through. This callback takes one argument - the "data" payload of the message. Messages do not *have* to include data (they can simply be used to indicate an event, and not transmit additional state). In the examples below, we'll see that you can call postal.publish() and postal.subscribe() directly, but you also have a much more intuitive option to fluently configure your subscription and publish handles. +All of these examples can be run live here: [http://jsfiddle.net/ifandelse/NTPcT/](http://jsfiddle.net/ifandelse/NTPcT/) + + + JavaScript: - // The world's simplest subscription - first let's look at the fluent configuration approach: - var name = undefined, - channel = postal.channel("Name.Changed"); + // The world's simplest subscription + var channel = postal.channel("Name.Changed"); // subscribe - channel.subscribe(function(data) { name = data.name }); + var subscription = channel.subscribe(function(data) { $("#example1").html("Name: " + data.name); }); // And someone publishes a first name change: channel.publish({ name: "Dr. Who" }); - console.log(name); // Dr. Who + subscription.unsubscribe(); + + // Subscribing to a wildcard topic using # // The # symbol represents "one word" in a topic (i.e - the text between two periods of a topic). // By subscribing to "#.Changed", the binding will match // Name.Changed & Location.Changed but *not* for Changed.Companion - var chgChannel = postal.channel("#.Changed"), - chgSubscription = chgChannel.subscribe(function(data) { - console.log(data.type + " Changed: " + data.value); + var hashChannel = postal.channel("#.Changed"), + chgSubscription = hashChannel.subscribe(function(data) { + $('
  • ' + data.type + " Changed: " + data.value + '
  • ').appendTo("#example2"); }); postal.channel("Name.Changed") .publish({ type: "Name", value:"John Smith" }); postal.channel("Location.Changed") .publish({ type: "Location", value: "Early 20th Century England" }); + chgSubscription.unsubscribe(); + + + + // Subscribing to a wildcard topic using * + // The * symbol represents any number of characters/words in a topic string. + // By subscribing to "DrWho.*.Changed", the binding will match + // DrWho.NinthDoctor.Companion.Changed & DrWho.Location.Changed but *not* Changed + var starChannel = postal.channel("DrWho.*.Changed"), + starSubscription = starChannel.subscribe(function(data) { + $('
  • ' + data.type + " Changed: " + data.value + '
  • ').appendTo("#example3"); + }); + postal.channel("DrWho.NinthDoctor.Companion.Changed") + .publish({ type: "Name", value:"Rose" }); + postal.channel("DrWho.TenthDoctor.Companion.Changed") + .publish({ type: "Name", value:"Martha" }); + postal.channel("DrWho.Eleventh.Companion.Changed") + .publish({ type: "Name", value:"Amy" }); + postal.channel("DrWho.Location.Changed") + .publish({ type: "Location", value: "The Library" }); + postal.channel("TheMaster.DrumBeat.Changed") + .publish({ type: "DrumBeat", value: "This won't trigger any subscriptions" }); + postal.channel("Changed") + .publish({ type: "Useless", value: "This won't trigger any subscriptions either" }); + starSubscription.unsubscribe(); + + + + // Applying ignoreDuplicates to a subscription + var dupChannel = postal.channel("WeepingAngel.*"), + dupSubscription = dupChannel.subscribe(function(data) { + $('
  • ' + data.value + '
  • ').appendTo("#example4"); + }).ignoreDuplicates(); + postal.channel("WeepingAngel.DontBlink") + .publish({ value:"Don't Blink" }); + postal.channel("WeepingAngel.DontBlink") + .publish({ value:"Don't Blink" }); + postal.channel("WeepingAngel.DontEvenBlink") + .publish({ value:"Don't Even Blink" }); + postal.channel("WeepingAngel.DontBlink") + .publish({ value:"Don't Close Your Eyes" }); + dupSubscription.unsubscribe(); + + + + // Using disposeAfter(X) to remove subscription automagically after X number of receives + var daChannel = postal.channel("Donna.Noble.*"), + daSubscription = daChannel.subscribe(function(data) { + $('
  • ' + data.value + '
  • ').appendTo("#example5"); + }).disposeAfter(2); + postal.channel("Donna.Noble.ScreamingAgain") + .publish({ value:"Donna Noble has left the library." }); + postal.channel("Donna.Noble.ScreamingAgain") + .publish({ value:"Donna Noble has left the library." }); + postal.channel("Donna.Noble.ScreamingAgain") + .publish({ value:"Donna Noble has left the library." }); + postal.channel("Donna.Noble.ScreamingAgain") + .publish({ value:"Donna Noble has left the library." }); + postal.channel("Donna.Noble.ScreamingAgain") + .publish({ value:"Donna Noble has left the library." }); + daSubscription.unsubscribe(); + + + + // Using whenHandledThenExecute() to invoke a function after handling a message + var whteChannel = postal.channel("Donna.Noble.*"), + whteSubscription = whteChannel.subscribe(function(data) { + $('
  • ' + data.value + '
  • ').appendTo("#example6"); + }).whenHandledThenExecute(function() { + $('
  • [Kind of a frivolous example...but this line resulted from the whenHandledThenExecute() callback]
  • ').appendTo("#example6"); + }); + postal.channel("Donna.Noble.*") + .publish({ value:"Donna Noble has left the library." }); + whteSubscription.unsubscribe(); + + + + // Using withConstraint to apply a predicate to the subscription + var drIsInTheTardis = false, + wcChannel = postal.channel("Tardis.Depart"), + wcSubscription = wcChannel.subscribe(function(data) { + $('
  • ' + data.value + '
  • ').appendTo("#example7"); + }).withConstraint(function() { return drIsInTheTardis; } ); + postal.channel("Tardis.Depart") + .publish({ value:"Time for time travel....fantastic!" }); + postal.channel("Tardis.Depart") + .publish({ value:"Time for time travel....fantastic!" }); + drIsInTheTardis = true; + postal.channel("Tardis.Depart") + .publish({ value:"Time for time travel....fantastic!" }); + wcSubscription.unsubscribe(); + + + + // Using withContext to set the "this" context + var ctxChannel = postal.channel("Dalek.Meet.CyberMen"), + ctxSubscription = ctxChannel.subscribe(function(data) { + $('
  • ' + data.value + '
  • ').appendTo(this); + }).withContext($("#example8")); + postal.channel("Dalek.Meet.CyberMen") + .publish({ value:"Exterminate!" }); + postal.channel("Dalek.Meet.CyberMen") + .publish({ value:"Delete!" }); + ctxSubscription.unsubscribe(); + + + + // Using withDelay() to delay the subscription evaluation + var wdChannel = postal.channel("He.Will.Knock.Four.Times"), + wdSubscription = wdChannel.subscribe(function(data) { + $('
  • ' + data.value + '
  • ').appendTo($("#example9")); + }).withDelay(5000); + postal.channel("He.Will.Knock.Four.Times") + .publish({ value:"Knock!" }); + postal.channel("He.Will.Knock.Four.Times") + .publish({ value:"Knock!" }); + postal.channel("He.Will.Knock.Four.Times") + .publish({ value:"Knock!" }); + postal.channel("He.Will.Knock.Four.Times") + .publish({ value:"Knock!" }); + wdSubscription.unsubscribe(); + ## How can I extend it? There are two main ways you can extend Postal: