Reactive Extensions (Rx) 现已开源
[原文发表地址] Reactive Extensions (Rx) is now Open Source
[原文发表时间] November 6, 2012 9:24 PM
自上次我和Erik Meijer一起制作有关.Net Reactive Extensions(Rx)的播客已有好几年了。从那个时候起,成千上万的人开始尽情在项目中使用Rx,并且很多开源项目如ReactiveUI(也可以在播客上看到)出现了。甚至Windows适用的GitHub也使用了Reactive Extensions。实际上,GitHub在Windows产品中大量使用了Rx。我在GitHub的一位朋友Paul说他非常喜欢这个模式,他们研发了一个Mac版本!
“ Windows适用的GitHub几乎对所有事情都使用Reactive Extensions ,包括网络请求, UI事件,子进程管理( git.exe )。通过使用Rx和ReactiveUI ,我们已经编写了一个快速,几乎100% 异步,响应迅速的应用,同时还有100% 确定,可靠的单元测试。 GitHub的桌面开发人员非常爱Rx ,甚至Mac团队创建了他们自己的Rx和ReactiveUI版本,被称为ReactiveCocoa ,现在已经在Mac使用,以获得类似的好处。
—— Paul Betts , GitHub
今天,微软开源技术宣布Reactive Extensions的开源的消息!你可以从https://rx.codeplex.com在Codeplex上使用git获取代码。你将无法抗拒这趟开源列车!祝贺这个伟大的团队!
这里包含了许多东西,因此热情已被点燃!这不仅有Rx.Net,还有C++库,以及JavaScript的RxJS!现在每个人都可以使用IObservable<T>和IObServer<T>玩弄它。
- Reactive Extensions:
-
- Rx.Net:Reactive Extensions(Rx)是一个实现异步和基于事件的程序的库,它使用了可察觉的序列和LINQ样式的查询运算符。
- RxJS:JavaScript的Reactive Extensions(RxJS)是一个在JavaScript中实现异步和基于事件的程序的库,它使用了可察觉的序列和LINQ样式的查询运算符,它可以用于浏览器和Node.js。
-
- Rx++:Native的 Reactive Extensions(RxC)是一个在C和C++中实现异步和基于事件的程序的库,它使用了可察觉的序列和LINQ样式的查询运算符。
- Interactive Extensions
-
- Ix:Interactive Extensions(Ix)是一个.Net库,它扩展LINQ to Object,提供许多在Rx可用的操作符,但是面向IEnumerable<T>。
- IxJS:JavaScript中的LINQ to Object开发和Interactive Extensions (Ix)
- Ix++:C++中供Native开发人员使用LINQ
一个学习有关为什么Rx有用的很好的方法是点击Rx Koan的工程或者阅读介绍Rx的在线电子书。
为什么我认为Rx很重要?它是一个在事件流上实现异步操作的方式。而不是连接点击事件和用事件处理程序管理所有事件的状态,你可以有效地用LINQ查询一个事件的无限流。你可以声明式的排序事件……不用标记,没有状态机。
例如,这里用鼠标按键和鼠标移动事件创建了一个拖拽事件(已设计好):
IObservable<Event<MouseEventArgs>> draggingEvent =
from mouseLeftDownEvent in control.GetMouseLeftDown()
from mouseMoveEvent in control.GetMouseMove().Until(control.GetMouseLeftUp())
select mouseMoveEvent;
更胜一筹的是,Rx让它更容易(或者更可能)地创建基于事件的异步测试,像来自Jafar Husain的此例
Rating rating = new Rating();
IObservable<Unit> test = // Unit is an object that represents null.
ObservableExtensions
.DoAsync(() => TestPanel.Children.Add(rating))
.WaitFor(TestPanel.GetLayoutUpdated()) // Extension method GetLayoutUpdated converts the event to observable
.DoAsync(() => rating.Value = 1.0) // Calls the Ignite EnqueueCallback method
.WaitFor( // waits for an observable to raise before going on
// listen to all the actual value change events and filters them until ActualValue reaches Value
rating
.GetActualValueChanged() // extension method that converts ActualValueChanged event to IObservable
.SkipWhile(actualValueChangedEvent => actualValueChangedEvent.EventArgs.NewValue != rating.Value))
// check to make sure the actual value of the rating item is set appropriately now that the animation has completed
.Assert(() => rating.GetRatingItems().Last().ActualValue == 1.0) // crawls the expression tree and makes a call to the appropriate Assert method
Test.Subscribe(() => TestPanel.Children.Remove(rating)); //run the test and clean up at the end.
这是一个很棒的时间相关的操作,让你随着时间移动模拟事件。注意Buffer和Subscribe的调用
var myInbox = EndlessBarrageOfEmail().ToObservable();
// Instead of making you wait 5 minutes, we will just check every three seconds instead. :)
var getMailEveryThreeSeconds = myInbox.Buffer(TimeSpan.FromSeconds(3)); // Was .BufferWithTime(...
getMailEveryThreeSeconds.Subscribe(emails =>
{
Console.WriteLine("You've got {0} new messages! Here they are!", emails.Count());
foreach (var email in emails)
{
Console.WriteLine("> {0}", email);
}
Console.WriteLine();
});
你可以使用await和async就像这个例子一样,在5秒后返回数字42:
static async void button_Click()
{
int x = await Observable.Return(42).Delay(TimeSpan.FromSeconds(5));
// x with value 42 is returned after 5 seconds
label.Text = x.ToString();
}
我在这里只是为您展示了我所喜欢的部分,但是一个人也可以轻松地在大学讲上10周有关Rx的课程,但我还只是一个初学者。
这里有更多Rx资源,请点击查看。祝贺这个伟大的团队在开源方面做出的贡献!