DOM EventStreams (take two on Streams): Request for feedback

Tab Atkins Jr. jackalmage at gmail.com
Thu Apr 18 18:34:11 PDT 2013


On Thu, Apr 18, 2013 at 5:11 PM, Domenic Denicola
<domenic at domenicdenicola.com> wrote:
> One bigger question: what is the DOM use case for event streams?
>
> That is, it's very clear what the DOM use cases are for binary data streams. (Most urgently, streaming XHR, but also perhaps unifying the many interfaces that use object URLs as a means of connecting separate streams of data; also exposing the browser's GZIP capabilities; and so on [1].)
>
> But for event streams it's less clear what urgent problem they solve. The example you've shown so far is basically just a different way of doing Object.observe, with some nice sugar and of course those combinators. But the basic capabilities of the platform are not expanded, and sugar seems like a library-level concern. Nevertheless, there's many allusions to DOM use cases in your blog posts, so a listing of those would be helpful.
>
> In other words: if there are many use cases for the DOM where event streams make sense, great! In the spirit of standardizing promises, it's good to standardize a common idiom so we don't do things in many different ways across the DOM APIs. But if the only use case is just to notify of property changes, Object.observe handles that nicely without streams. What else needs event streams?

Almost every use-case for streams *could* be done by just exposing the
data as a property on some object and using Object.observe.  That
loses all the really wonderful control-flow properties of streams,
though.  One simple but very nice example is explained in my blog
while illustrating the switch() method.  I'll reproduce it here.

Say you want to provide autocomplete suggestions as the user types
into some field, based on data on your server.  Using today's
technologies, this is absolutely possible:

1. Register an "input" listener on the input.
2. Possibly throttle the input events to keep them from coming in too quickly.
3. As the input events come in, construct an XHR to retrieve
suggestions from your server.
4. As each XHR finishes, verify that the results aren't already
obsolete by a later XHR returning faster.
5. If they're not obsolete, update your UI with the returned suggestions.

Actually writing the code to do all this is surprisingly non-trivial.
With EventStream and Future, though, it becomes trivial:

EventStream.listen(input, "input")
  .throttle(100)
  .map(e=>getJSON('http://example.com', e.target.value))
  .switch()
  .then(updateUI);

(Assuming that XHR defines a function named getJSON() which returns a Future.)

That's literally all the code you need.  You can even trivially handle
and recover from XHR errors by adding a second callback to the map()
call.

Even for the "basic" use-cases like I've pointed to in my Font Load
API proposal, event streams make code *way* easier to write.  Try
writing code that just updates the UI to tell whether there are
currently any fonts loading, based on Object.observe().  It's less
trivial than one would think:

Object.observe(document.fonts, changes=> {
  if( changes.filter(change=> change.type==="name" &&
change.name==="loadStatus").length )
    updateLoadingUI(document.fonts.loadStatus);
});

Most of this is completely boilerplate, and occupied solely with
"fixing" the data from Object.observe into a better form.  On the
other hand, with a ValueStream:

ValueStream.watch(document.fonts, 'loadStatus').squash().then(updateLoadingUI);

(And I'm considering folding "squash" into the default behavior of
ValueStreams, too, so it would be even simpler.)

Yes, a lot of the weight of Object.observe could be lessened by syntax
sugar.  At least part of the point of ValueStream is to *be* that
syntax sugar.

Ultimately, though, I'll just point you back to your own blog post at
<http://domenic.me/2012/10/14/youre-missing-the-point-of-promises/>.
^_^  Just like how Futures capture the notion of async control flow
and errors, Stream capture the same for *loops*.

~TJ


More information about the es-discuss mailing list