昨天我看了Screencast Writing your first Rx Application(在频道9),Wes Dyer展示了如何使用Reactive Extensions (Rx)实现Drag'n'Drop。东西,我还是不明白:Rx:可观测量是否像IEnumerable那样“可重复”,如果不是,这个代码是如何工作的?
迎截屏结束,韦斯代尔类型如下:
var q = from start in mouseDown
from delta in mouseMove.StartsWith(start).Until(mouseUp)
.Let(mm => mm.Zip(mm.Skip(1), (prev, cur) =>
new { X = cur.X - prev.X, Y = cur.Y - prev.Y }))
select delta;
简而言之,q
是可观察到的是推动了鼠标移动的坐标增量向其用户。
我不明白的是如何mm.Zip(mm.Skip(1), ...)
可能工作!?
据我所知,IObservable
是不可枚举的,因为IEnumerable
是。由于IEnumerable
的“拉”性质,它可以反复迭代,总是产生相同的项目。 (至少应该是就是所有乖巧枚举的情况。)IObservable
的工作方式不同。项目被推送给订阅者一次,就是这样。在上面的例子中,鼠标移动是单个事件,如果没有记录在内存中就不能重复。
那么,.Zip
与.Skip(1)
的组合如何工作,因为他们正在处理的鼠标事件是单一的,不可重复的事件?此操作是否要求mm
两次独立“查看”?
仅供参考,这里有Observable.Zip
方法签名:
public static IObservable<TResult> Zip <TLeft, TRight, TResult>
(
this IObservable<TLeft> leftSource, // = mm
IObservable<TRight> rightSource, // = mm.Skip(1)
Func<TLeft, TRight, TResult> selector
)
P.S:我刚才看到有另一个screencast on the Zip
operator这是相当有见地。
_ @ Nappy_,感谢您解释“热”与“冷”的术语位。当我问这个问题时,我缺乏恰当的词汇,这让事情变得更加清晰。 – stakx 2010-09-04 21:36:29