- From: Jonas Sicking <jonas@sicking.cc>
- Date: Wed, 20 Feb 2013 14:38:10 -0800
- To: David Bruant <bruant.d@gmail.com>
- Cc: public-sysapps@w3.org, Mounir Lamouri <mounir@lamouri.fr>
On Wed, Feb 20, 2013 at 8:09 AM, David Bruant <bruant.d@gmail.com> wrote: > Le 20/02/2013 16:48, Jonas Sicking a écrit : > > On Feb 20, 2013 12:15 AM, "David Bruant" <bruant.d@gmail.com> wrote: >> >> Le 20/02/2013 02:06, Jonas Sicking a écrit : >> >>> On Tue, Feb 19, 2013 at 2:07 PM, David Bruant <bruant.d@gmail.com> wrote: >>>> >>>> Le 18/02/2013 16:35, Mounir Lamouri a écrit : >>>> >>>>> On 18/02/13 15:15, Marcos Caceres wrote: >>>>>> >>>>>> On Monday, 18 February 2013 at 09:50, Kenneth Rohde Christiansen >>>>>> wrote: >>>>>> >>>>>>> Hi there, >>>>>>> >>>>>>>> Examples Jonas showed using DOMFuture could just work with >>>>>>>> DOMRequest >>>>>>>> if >>>>>>>> we add this .then() method. >>>>>>>> >>>>>>>> Also, we could imagine stuff like: >>>>>>>> getSomeData().then(function(data) { >>>>>>>> return getDataRelatedToThoseData(data); >>>>>>>> }).then(function(data) { >>>>>>>> show(data); >>>>>>>> }); >>>>>>>> >>>>>>>> I have a patch for Gecko implementing that. >>>>>>> >>>>>>> I like this pattern. It also seems closer to what MS are using in >>>>>>> their Windows 8 JS APIs. >>>>>> >>>>>> >>>>>> Not that just adding .then() does not address other issues with the >>>>>> API. >>>>>> David Braunt articulated this best in [1]: >>>>>> >>>>>> "In my opinion, one of the most absurd example is the DOMRequest thing >>>>>> which >>>>>> looks like: >>>>>> { >>>>>> readonly attribute DOMString readyState; // "processing" or "done" >>>>>> readonly attribute DOMError? error; >>>>>> attribute EventListener onsuccess; >>>>>> attribute EventListener onerror; >>>>>> attribute readonly any? result; >>>>>> }; >>>>>> >>>>>> Read it carefully and you'll realize this is actually a promise... but >>>>>> it has this absurd thing that it has to have both an error and result >>>>>> field while only one is actually field at any given point. >>>>> >>>>> FWIW, DOMFuture has .value and .error too. >>>>> >>>>> Anyway, it's quite not clear why having .{value,result} and .error is a >>>>> bad thing. If the DOMRequest is used as a promise, it's unlikely those >>>>> fields would be used anyway. If those fields have to be used (ie. if a >>>>> consumer wants to access the result outside of a .then(), .done() or >>>>> promise-like methods) >>>> >>>> <digression> >>>> We can wonder whether this (need to access the value outside >>>> then/catch/done) ever happens. I have never had the need in a 8 months >>>> experience. >>>> I don't think I've seen a context in Gaia where that was the case either >>>> (where a value was needed outside the context of an onsuccess/onerror). >>>> Likewise for the state attribute, to be fully honest. I'm interested if >>>> others have different experience to share on this point, though. >>>> >>>> Recently, the best definition I have come up with for promises was [1]: >>>> "a promise is an event emitter of a unique "success" xor "error" event. >>>> .then/.fail replace addEventListener/on". >>>> This follows a set of reflections of the idea that objects shouldn't be >>>> thought as "properties+methods", but rather "properties+methods+events" >>>> and >>>> some recurrent idioms (like promises and streams) are nothing but >>>> abstractions built on top of events. >>>> </digression> >>>> >>>> I haven't brought up this concern about the properties, because I feel >>>> it's >>>> a minor one. My personal short-term goal is to help have Future/Promise >>>> as >>>> soon as possible built in the platform whether they fit my own vision or >>>> not. >>>> >>>> I'm repeating what I've said elsewhere, but what we need for Futures to >>>> be >>>> helpful: >>>> 1) chainable .then >>>> 2) (~optionally, but excellent for readability in some cases) chainable >>>> .fail/catch >>>> 3) .done to end the chain (and have the devtools report uncaught errors >>>> at >>>> the end of the chain) >>>> 4) A combining mechanism à la Q.all >>>> This one could be optional and added as a library, but I fear people >>>> will >>>> just mess up their libraries with off-by-one errors, etc., so it'd be >>>> better >>>> to have it built-in. >>>> 5) the consumer of a promise can't resolve it >>>> >>>> Besides these 5 points, I personally won't fight over anything really >>>> hard. >>>> The .result/.error properties are beyond these 5 points. The name >>>> Future/Promise is also beyond these 5 points :-p >>> >>> This sounds like excellent feedback into the DOMFuture work. I >>> personally agree with all of it except number 3. That seems like a >>> nice-to-have to me. >> >> I really insist on this one. >> One particularly annoying aspects of async programming is that you have no >> stack trace you don't handle an error. >> >> f.then(function(){ >> >> }) >> .then(function(){ >> // an error is thrown here by library code and you didn't expect >> it >> }) >> .then(function(){ >> >> }).done() >> >> Without done, the unexpected error remains silent, your program doesn't >> work, you have no idea why. When doing async testing, it often means one of >> your async test just timeouts, which isn't very helpful. >> I just came across this yesterday on a Node project. Working with a >> colleague, trying to pin down an issue, I sent him the stack trace, and he >> just answered "useless, as usual", because that's really the experience of >> async debugging. Promises/futures offer some hope. >> With done, you can be told an unhandled error happened. The Q library >> throws the unhandled error (which no one really catches, because the error >> is thrown in its own event loop turn), but that's a library. With native >> futures, the devtools can log the error and that's largely enough. >> Additionally, with native support for DOMFuture, the devtools can know >> exactly where the future comes from and can tell us which future was the >> first one to be broken and provide the full list of all futures involved >> (like a stack trace... let's call that a future trace?). Super helpful. >> >> When you use a future every once in a while, .done is a nice to have. If >> you use chained futures extensively all over your code, .done really makes a >> difference. > > Sounds like you should file an issue on DOMDuture because this is not how it > currently works. > > I assume you're referring to .done (tell me if that's not the case). > > I read [1]: > void done(optional AnyCallback onaccept, optional AnyCallback onreject); > So the .done method provides a last option to handle yet-unhandled errors > and mostly importantly, it doesn't return anything meaning it has no other > future to propagate an unhandle error to. > So if no onreject callback is passed, devtools can consider an unhandled > error as... well... unhandled and log it... And hopefully, the future chain > was recorded in the background, so more than just the error, it's possible > to know where the error comes from and what its "path" was. > > Also [2]: > // What is clear is that no matter what approach is pursued, integration > // with developer tooling is key. Developer consoles SHOULD log un-caught > // errors from future chains. That is to say, if future.done(onresponse); is > // the only handler given for a resolver which is eventually rejected, > // developer tools should log the unhandled error. > > Integration with devtools shouldn't be part of the spec per se. However, the > feature is designed with devtools integration in mind and from what I read, > I feel it all describes what I expect from .done and the potential devtool > integration. > What makes you feel there is a mismatch between the proposed DOMFuture and > what I described? > > David > > [1] > https://github.com/slightlyoff/DOMFuture/blob/0a48424390229ddca6b5cdad10d414a400eb7d0c/DOMFuture.idl#L303 > [2] > https://github.com/slightlyoff/DOMFuture/blob/0a48424390229ddca6b5cdad10d414a400eb7d0c/DOMFuture.idl#L230-L234 In the current DOMFuture proposal, .then() and .done() have exactly the same script-visible behavior other than that .done() doesn't return a new DOMFuture. A valid implementation of .done() would be: DOMFuture.prototype.done = function(accept, error) { this.then(accept, error); } Note that there is no "return" statement there which means that the return value from .then() is dropped on the floor. Semantically they might have different meaning, and technically the platform might do different error reporting. But it's just as possible for script to catch errors using .then() as it is to catch them using .done() as the draft currently stands. / Jonas
Received on Wednesday, 20 February 2013 22:39:07 UTC