slightlyoff / Promises

DOM Promises IDL/polyfill
Apache License 2.0
154 stars 28 forks source link

Handling "Watches" #28

Open PaulKinlan opened 11 years ago

PaulKinlan commented 11 years ago

I am attempting to map the Geolocation API to the DOMFuture API, getPostition seems pretty simple. However the watchPosition API and the associated clearWatch are slightly troublesome.

Firstly, watchPostition is an asynchronous API that returns a value immediately (like setInterval and setTimeout) and then "onSuccess" is called multiple time as the position changes until you call clearWatch.

I am not sure how this maps to DOMFutures API, where to me at least, it seems very much like .then() will only be called once before passing to the next .then in the chain. Should I be using the Progress Future?

If we use the ProgressFuture, how should one handle the "watchId" so that the event can be cancelled. Would it be ok to assume the .value property returned is the watchId?

domenic commented 11 years ago

Futures represent a single asynchronous operation, i.e. a function call that instead of immediately returning/throwing eventually accepts/rejects. It sounds like they are not a good fit for your use case, which is more suited to events.

PaulKinlan commented 11 years ago

It leaves me in a bind. The API's that we have now are generally pretty mixed in terms of async usage and it seems odd to use Events in one API method, and Futures in another.

ProgressFutures in this repo seems like it covers the "watch" usecase, but it does return a trackingId right now.

The idea I had in my head was you might have:

watchPosition()
   .progress(function(v) { console.log("watching" + v); if(count % 10)  v.cancel();  })  // only do it 10 times
   .done(function() {  console.log("Done watching"); })

I think I am thinking about how to wrap the current API, rather than actually create a sane API. In an ideal world you wouldn't call clearWatch because it wouldn't exist.

domenic commented 11 years ago

The API's that we have now are generally pretty mixed in terms of async usage and it seems odd to use Events in one API method, and Futures in another.

This doesn't seem odd to me at all. That's like saying "it seems odd to use arrays in one API method, and objects in another." They cover different use cases: events are for things that happen sporadically, and multiple consumers might want to be notified about (in short, the observer pattern) whereas futures are simply asynchronous function calls. APIs can easily have both function calls and values you might want to observe.

In particular, I think it's much more distasteful to twist the "progress" concept into a poor-man's event substitute, than it is to use both events and futures.

domenic commented 11 years ago

Another way of putting it: futures are not meant to replace all instances of events in DOM APIs. Rather, they're meant to replace the specific use cases where:

If you find yourself in that scenario, it's more likely that the underlying operation you're trying to model is an asynchronous function call, which is best represented by returning a future. If your events don't fit this pattern, futures are not meant to address your use case.

PaulKinlan commented 11 years ago

Understood. I think to some extent, it is a mixture of usecases for the existing API. For example, I have seen a lot of people use watchPosition to wait for a more accurate fix on the current location (Location Dithering if you will), in which case in my head progress makes sense (you are progressing to a final result). On the other hand, people use it to track movement over time.

Anyway, I am going to play with specing the Geo APi a little more if no one minds. I have a need for a unfied async model as I am using Geo, IndexedDB and other methods that when combined async'ly cause my code to be horrid.

slightlyoff commented 11 years ago

I do think the geolocation update scenario needs to be done with events. Getting a single update is what Futures are for.

slightlyoff commented 11 years ago

@PaulKinlan : can you send a pull request or a gist with the updated IDL for this? I'd love to add an updated geolocation API to the reworked_APIs directory.