4 ms·
Reactor.js: simple reactive programming for Javascript
- ncasenmare 13y agoObject.observe() is an upcoming feature for JavaScript, which allows you to add listeners to object's properties changing. With that, you could do the same thing as this library, but without this library. Still, I'm a fan of reactive programming, so thanks for this anyway!
- stevensanderson 13y agoI wish this were true, but unfortunately not. Object.observe doesn't provide any 'read' notifications, so you wouldn't be able to detect dependencies like this does.
- noelwelsh 13y agoIt's cool to see this kind of stuff coming out. Flapjax was way ahead of it's time -- too far ahead it seems.
- sailfast 13y agoI appreciate that this library focuses on being lightweight and easy to use, and I look forward to experimenting / refactoring some code with this. I'll be interested to see how this library works alongside other javascript packages for visualization and display since it doesn't have bindings - things like Knockout.js and its custom bindings always seemed rather complicated to execute, but that could've been because I didn't fully understand what was going on behind the scenes.
- cmwelsh 13y agoMy favorite functional reactive programming library for JavaScript is Bacon.js: https://github.com/raimohanska/bacon.js https://github.com/raimohanska/bacon.js "It's the _ of Events. Too bad the symbol ~ is not allowed in Javascript."
- themstheones 13y agoIf you really care you could use something like window['~'].
- Stratoscope 13y ago"Turns your event spaghetti into clean and declarative feng shui bacon, by switching from imperative to functional." Maybe I'm just old-fashioned, but if you want to get me to try out some JavaScript library, this ain't gonna do it. Feng shui bacon? Really? How about skipping the BS and showing me some real code and compare it with the code I would have written otherwise? (This rant is not directed at you, but at the Bacon author.)
- alipang 13y agoTo be fair, there are plenty of examples. If you read to the next paragraph it's in the list. There is the examples folder, as well as the TodoMVC implementation. Disclaimer: Bacon.js contributor
- Stratoscope 13y agoI sincerely apologize for my bad attitude in my previous comment. It was uncalled-for. Thanks for not taking too much offense, and thanks for the pointer to the examples. Perhaps my feng shui was off balance yesterday!
- judah 13y agoKnockoutJS (KO) does essentially the same thing: What KO calls observable, Reactor calls signal. What KO calls computed, Reactor calls observer. The ReactiveExtensions library (including Rx.js) has been doing this thing for several years now, only more sophisticated than either KO or Reactor: https://github.com/Reactive-Extensions/RxJS https://github.com/Reactive-Extensions/RxJS
- fynyky 13y agoYep. This is an attempt to do what knockout does in a simpler form with less syntax
- judah 13y agoInteresting. Where does the less syntax come in? I'm looking at your signal and observer, and it looks like the same syntax as KO.
- fynyky 13y agoOne difference is that there is no need to explicitly subscribe to signals. For general functions, knockout requires manually declaring "myViewModel.property.subscribe(...)" for each model you need to subscribe to. In contrast, Reactor's observer blocks automatically detect which signals you have read and sets up the subscriptions automatically. Knockout has a different class for ko.computed vs ko.observable. For Reactor you use "Signal" for both and just pass in a function when its computed. Additionally there is no need for the trailing "this" at the end of ko.computed.
- dustingetz 13y agoknockout is not FRP. Knockout uses single events, FRP uses event streams. Here's a quote from Knockout's creator. http://stackoverflow.com/questions/5101113/whats-the-difference-between-knockout-js-and-rx-js http://stackoverflow.com/questions/5101113/whats-the-differe...
- sinkasapa 13y agoOther than the fact that this is more minimal, does anyone have any insight in to how this compares to Bacon, Flapjax or RxJs? I've been wanting to give this coding style a try but tend to get turned off by the size and complexity of the existing libraries. I look at this as a personal fault not that of the libraries. I plan to read the source of Reactor.js, which is very well commented. Until then, does anyone know if this is a "complete" implementation or is something fundamental missing? Is it push or pull?
- simonhughes22 13y agoKnockout does this but it also has declarative html bindings, so there is no need to do the observer logic, you just add some lightweight annotations to your html and it binds for you. I think this is a lightweight alternative to ko, but ko does a lot more and is very easy to use.
- sinkasapa 13y agoBut I only want the reactive programming part. How do I take out all the parts that I don't want or need in knockout?
- fynyky 13y agoIt's "complete" as far as I've tested it. Changes are automatically pushed out without any additional work. In terms of how it compares - It's based off the same reactive programming principles but is trying to keep the additional syntax and complexity to a minimum.
- sinkasapa 13y agoIt looks just perfect for me. And to those who keep on talking about knockout.js, this is great because not everyone wants all the bloat of yet another big "do everything" JS library.
- alipang 13y agoBacon/Rx allows you to work with an event stream abstraction, which assigns responsibility quite differently. Bacon is more like excel in the sense that a cell defines /itself/ in terms of other cells A1 = B1 + C1 or in Bacon var as = bs.combine(cs, (b,c) -> b + c) The style in ko/reactor is often inverted. One opens a 'bus' or 'signal', to which an arbitrary set of others push values. var as = Signal() function bs() { as(...) // push value } Of course, the point of Bacon is that Rx.js does not quite define an event stream abstraction, as it has the (kinda weird) distinction between hot and cold observables which can be way surprising.
- oakaz 13y agoHi, I'm also working on a minimalistic reactive programming concept; https://github.com/azer/attr https://github.com/azer/attr I have a library called "attr", which mixes pubsub (npm.im/pubsub) and new-prop (npm.im/new-prop) And you simply get; foo = attr(3) bar = attr().getter(function(){ return foo() + 5 }) foo() // => 3 bar() // => 8 foo(5) bar() // => 10 They are simply based on a very simple pubsub interface (publish,subscribe). So you can also do; foo = attr(3) bar = bar() foo.subscribe(function(update){ bar(update + 5) }) bar.subscribe(function(update){ update // => 10 }) foo(5) The advantage of this concept is, it's really easy to extend and optimize. Here is an example that I use new-list (npm.im/new-list) and new-object new-object (npm.im/new-object) to create some lists and objects, and use subscribe (npm.im/subscribe) module to create one callback for observing all changes: people = newObject({ 'jack': 23, 'smith': 27 }) fruits = newList('apple', 'orange') foo = attr() bar = attr() foo.subscribe(function(update){ bar( update + 5 ) }) subscribe(people, fruits, bar, function(updates){ updates[0].params // => { add: { John: 21 }, rm: ['smith'] } updates[1].params // => 12 }) people.rm('smith') people('John', 21) foo(7) My work is done until here. And here is the part that I'm actually working on: http://github.com/azer/new-reactive http://github.com/azer/new-reactive It's a library for creating your own HTML binding abstractions like AngularJS. But your own that you can share, that can be extended by somebody else or can be mixed with another namespace of abstractions. Which means, if your company is named "foo" and you're using a library called "bar", you can have bindings like; <button foo-play="song" bar-content="i18n.play"></button>
- geuis 13y agoOk, I can follow along with your examples. But I still don't get the "why" of it. Initially it kind of seems like extra mental gymnastics and wrapping your code in an extra level of abstraction. I'm not sure what the point is. Just as some extra background, I've read the README with the parent library this comment thread is based on. I've read the linked Stack Overflow question and answer linked from it about reactive programming. I worked my way partly through the 1998 article with the bouncing kids heads. I recently did some work with Knockout for a client. I've had some exposure to reactive programming, but I still haven't had a light bulb moment that demonstrates why this style is better. With Knockout, I find having a variable automatically update its value interesting. I like the pub/sub concept of having a variable publish its changes to any subscribers. This is useful in many frameworks including Knockout, Backbone, and more. I think in Knockout simply executing an observable inside a function makes that function subscribe to the variable is cute. But just in my opinion, it feels like to much magic and magic is fragile. But to ask the most pertinent question, can you provide a real-world situation of at least moderate complexity where using a programming model like your "attr" is going to be better than a more traditional way of solving it? Thanks in advance! I'm looking forward to learning something new.
- lightblade 13y agoWould be great if you can provide a simple playground app to let people try it out. It can be as simple as a github page that loads the lastest .js file into a script tag.
- baobaosaur 13y agonice!
- agersant 13y agoMaybe that's just me but I think the basic example fails at conveying how this library can be useful. http://i.imgur.com/gMuRxa0.jpg http://i.imgur.com/gMuRxa0.jpg