Re: PROPOSAL: Use events instead of callbacks

Harald Alvestrand wrote:
> Q1: Could someone point me at a good description of how events work, and
> where their definition lives?

http://www.w3.org/TR/dom/#events

>
> Q2: This style would create an object that represents "the head of the
> MediaStream". Would it be logical to move some of the manipulation
> functions we've been thinking of for MediaStreams onto that object, if
> this is adopted?

You probably want such functions on the MediaStream object directly. 
Assuming you're obtaining secondary use of a MediaStream object (i.e. 
you didn't obtain the MediaStream via your own EventListener) then you 
can still apply these methods to that secondary object directly.

> I'm thinking in particular of the API for turning on/off echo
> cancellation, which should be conceptually as close to the microphone as
> possible.
>
> Q3: If we adopted this behaviour, would the function
>
> function oldStyleGetUserMedia(opts, success, fail) {
> var media = navigator.getUserMedia(opts);
> media.addEventListener('onsuccess', function(event e) { success(e.stream) }
> ... same for failure ..
> }
>
> constitute a drop-in replacement for "old-style" code, or are there
> subtleties here that need exploring?

I'm not in favor of changing from the callbacks approach but in a 
*worst-case scenario*, we could manage a change such as this as long as 
we choose a different name for the new function.

The onus must still be to explain why we would need this change though. 
I've been on the events vs callbacks merry go round more than a couple 
of times before and the differences seem to mostly boil down to personal 
and ideological preferences rather than real technical flaws or 
deficiencies of either approach.

>
> Q4: could we use a different name for the new function?

See response to Q3 above.

>
> Not speaking at all to the "is this hard for existing implementations"
> argument......
>
> On 03/06/2012 08:47 PM, Travis Leithead wrote:
>> If you take this approach, then you'll want to use the DOMError
>> instead...
>>
>>> NavigatorUserMedia.error -> A NavigatorUserMediaError object assigned
>>> (null otherwise).
>> NavigatorUserMedia.error -> A DOMError object assigned (null otherwise)
>>
>> :)
>>
>> I understand that there are some general concerns with this design due
>> to early existing implementations of the callback approach.
>> Specifically, Rich and someone from Google should reply with their
>> thoughts.

Right. We released navigator.getUserMedia in Opera Mobile 12 in to the 
hands of multi-millions of users so this is not a trivial argument at all.

It's important to explain what benefits we obtain against the callbacks 
approach. Perhaps you could provide specific use cases where the 
callback approach is failing to date?

>>
>> -Travis
>>
>>> -----Original Message-----
>>> From: Anant Narayanan [mailto:anant@mozilla.com]
>>> Sent: Tuesday, March 06, 2012 11:38 AM
>>> To: public-media-capture@w3.org
>>> Subject: PROPOSAL: Use events instead of callbacks
>>>
>>> What
>>> --
>>> Change the function signature of navigator.getUserMedia to return a
>>> 'NavigatorUserMedia' object that extends 'EventTarget' (fully
>>> specified in
>>> http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventTarget)
>>> and
>>> eliminate the use of success and error callbacks:
>>>
>>> var media = navigator.getUserMedia({'video':true});
>>> media.addEventListener('onsuccess', function(Event e) {
>>> e.target.stream }, false);
>>> media.addEventListener('onerror', function(Event e) { e.target.error
>>> }, false);
>>>
>>> Why
>>> --
>>> Events are preferred to callbacks in almost all WebAPIs in wide use
>>> today,

The Geolocation API uses callbacks and represents the closest match that 
we have in standards to the intended operation of getUserMedia.

>>> examples include XHR and IndexedDB. Events are more flexible than
>>> callbacks
>>> as they allow multiple listeners, chaining, and bubbling; none of
>>> which are
>>> supported by a single callback (as currently specified in the
>>> specification). Some applications will not need the flexibility
>>> provided by
>>> Events, but it is trivial to emulate a single callback system built
>>> on top
>>> of events and is also a common idiom for web APIs:

Perhaps you could provide concrete use cases where multiple listeners, 
chaining and bubbling make it essential that we revisit the callbacks vs 
events discussion.

>>>
>>> var media = navigator.getUserMedia({'audio':true});
>>> media.onsuccess = function(e) { e.target.stream; };
>>>
>>> How
>>> --
>>> The function getUserMedia can be changed to return an object (the
>>> proposal
>>> calls it a 'NavigatorUserMedia' object) that extends 'EventTarget'.
>>> Event
>>> listeners can be added and removed using the standard event target
>>> methods.
>>> The 'Event' object passed to the onsuccess and onerror event
>>> listeners will
>>> have Event.target set to the 'UserMedia' object, which as the
>>> following two
>>> properties:
>>>
>>> NavigatorUserMedia.stream -> A MediaStream object assigned (null
>>> otherwise).
>>> NavigatorUserMedia.error -> A NavigatorUserMediaError object assigned
>>> (null otherwise).
>>>
>>> I look forward to your feedback!

Thanks for taking the time to draft this. I think we could revisit a 
number of the technical details in the proposal at a later time but more 
fundamental questions remain for making this change as I've outlined above.

Perhaps you could clarify the exact nature of the problems that events 
solve over callbacks via scripting use cases and we could go from there.

As Harald said, such a change would not be at all trivial for existing 
implementations.

Cheers,

Rich

Received on Wednesday, 7 March 2012 12:45:34 UTC