Note that there are some explanatory texts on larger screens.

plurals
  1. PORx: Are observables "repeatable" like IEnumerable, and if not, how does this code work?
    text
    copied!<p>Yesterday I watched the screencast <a href="http://channel9.msdn.com/posts/J.Van.Gogh/Writing-your-first-Rx-Application/" rel="nofollow noreferrer"><strong>Writing your first Rx Application</strong></a> (on Channel 9) where Wes Dyer shows how to implement Drag 'n' Drop using <a href="http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx" rel="nofollow noreferrer">Reactive Extensions (Rx)</a>. Something that I still don't understand:</p> <p>Towards the end of the screencast, Wes Dyer types in the following:</p> <pre><code>var q = from start in mouseDown from delta in mouseMove.StartsWith(start).Until(mouseUp) .Let(mm =&gt; mm.Zip(mm.Skip(1), (prev, cur) =&gt; new { X = cur.X - prev.X, Y = cur.Y - prev.Y })) select delta; </code></pre> <p>Briefly, <code>q</code> is an observable that pushes the mouse move coordinate deltas to its subscribers.</p> <p>What I don't understand is how the <strong><code>mm.Zip(mm.Skip(1), ...)</code></strong> can possibly work!?</p> <p>As far as I know, <code>IObservable</code> is not enumerable in the sense that <code>IEnumerable</code> is. Thanks to the "pull" nature of <code>IEnumerable</code>, it can be iterated over again and again, always yielding the same items. (At least this <em>should</em> be the case for all well-behaved enumerables.) <code>IObservable</code> works differently. Items are pushed to the subscribers once, and that was it. In the above example, mouse moves are single incidents which cannot be repeated without having been recorded in-memory.</p> <p>So, how can the combination of <code>.Zip</code> with <code>.Skip(1)</code> possibly work, since the mouse events they're working on are single, non-repeatable incidents? Doesn't this operation require that <code>mm</code> is "looked at" independently twice?</p> <hr> <p>For reference, here's the method signature of <code>Observable.Zip</code>:</p> <pre><code>public static IObservable&lt;TResult&gt; Zip &lt;TLeft, TRight, TResult&gt; ( this IObservable&lt;TLeft&gt; leftSource, // = mm IObservable&lt;TRight&gt; rightSource, // = mm.Skip(1) Func&lt;TLeft, TRight, TResult&gt; selector ) </code></pre> <hr> <p><strong>P.S.:</strong> I just saw that there's another <a href="http://channel9.msdn.com/posts/J.Van.Gogh/Reactive-Extensions-API-in-depth-Zip/" rel="nofollow noreferrer">screencast on the <code>Zip</code> operator</a> which is quite insightful.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload