-
Notifications
You must be signed in to change notification settings - Fork 94
Closed
Labels
Description
With current design, the only way to process resolved value and be sure that unhandled exceptions are exposed, is via following
promise.then(function (value) {
setTimeout(function () {
// Process value
}, 0);
}, function (err) {
setTimeout(function () {
// Handle error
}, 0);
});
Which is poor solution for many reasons:
- Affects performance:
- Creates promise objects we don't need
- forces processing to further tick
- Unintuitive
- Verbose
In many promise implementations, there's already promise.done
, which doesn't create any new promise, and invokes callbacks naturally (outside of try/catch clause).
As done
cannot be implemented on top of available API, I think it's very important to include it in spec.
As side note, why do Promise.prototype.catch
is specified? It can be very easily configured on top of the rest of the API, and it's usability is low.
Metadata
Metadata
Assignees
Labels
Projects
Milestone
Relationships
Development
Select code repository
Activity
annevk commentedon Sep 4, 2013
The outcome of the previous TC39 discussion was to get rid of done() for now. It might resurface one way or another, but adding it back before revisiting that discussion seems bad, and we can easily revisit that after we ship the basic design.
medikoo commentedon Sep 4, 2013
@annevk Thanks for clarification. I just wanted to point that without that, spec (even in most basic form) shouldn't be perceived as complete.
domenic commentedon Sep 4, 2013
done
's job will be done by integrating unhandled rejection tracking functionality into dev tools. Most TC39ers, from what I understand, as well as myself, perceive that as enough for the spec to be complete.Furthermore, there is no need for implementations to create promise objects only to have them immediately GCed. Unlike user-space promise implementations, that is easily detectable; such
then
invocations whose return values are ignored can simply not create a new promise object.medikoo commentedon Sep 4, 2013
Monitoring solution significantly raises complexity of implementation, and brings many other issues. I haven't seen it yet either implemented or specified in a way that would really solve above issue.
It's really hard to understand for me, why you advocate after something that is difficult to implement, not logical and not natural for JavaScript, when real solution can be so simple, and as far as I remember from discussion on es-discuss, many were concerned about that.
Can you explain exactly, how? Static code analysis?
annevk commentedon Sep 4, 2013
Implementations can report unhandled exceptions during GC to the error console.
medikoo commentedon Sep 4, 2013
@annevk You mean that when promise would be GC'ed, implementation would check whether reject value was retrieved and if not, it would report to reject value to error console (?)
What if implementation would completely implement this spec, but won't provide this functionality?
I hope you understand that such implementation would turn out as hardly usable.
...and again it's not error handling that JS programmers are used to, it can be simple and should be in my opinion.
annevk commentedon Sep 4, 2013
If implementations do not provide adequate debugging, they'll be used less. This is the same for any number of features on the platform. And simple is not necessarily good here, as people will use .then() and forget about things.
medikoo commentedon Sep 4, 2013
@annevk only with
done
programmer can have full control over error handling, and promise libraries should provide that.Argument that having both
then
anddone
is too much for programmer's head is quite controversial to me. Both methods serve two different use cases, and both are equally important.Also looking at other API examples you can see it's not true. e.g. programmers somehow manage well both
map
andforEach
on arrays. I haven't seen complains that we should removeforEach
and just usemap
, as it's confusing and implementation might automatically not create returned arrays if it detects it's not taken.annevk commentedon Sep 6, 2013
Per http://lists.w3.org/Archives/Public/public-script-coord/2013JulSep/0571.html we should reconsider this.
domenic commentedon Sep 6, 2013
Might be time for @wycats to step in, as he's one of the most prominent anti-
done
people.wycats commentedon Sep 6, 2013
I don't feel like arguing with BE. I strongly believe that this is a scenario solving mistake that we are hastily making as promises have gained popularity.
I have come to believe that the fact that done is needed at all is a fatal flaw in the current specification. Swallowing honest-to-god exceptions (TypeError, ReferenceError) as though they were promise rejections was just a mistake.
At minimum, it should be possible to configure a promise library to bubble out exceptions, for debugging.
I would like it if we didn't repeat this mistake with DOMPromises, and avoid compounding the mistake by complicating the API.
mhofman commentedon Sep 6, 2013
I've been reading and thinking a lot about this error / rejection handling issue in recent days and I've become convinced that the answer is in keeping Promise's semantics simple so that it mirrors synchronous calls.
In that sense,
then
is used to execute another operation after the previous one completes andcatch
is used to handle an operation failing. For the same reason, I would also like to seefinally
as I expressed before in #18 but I guess I could live without it for now.Discriminating on the failure's type is a dangerous business since I doubt we can be sure a TypeError / ReferenceError is always due to a promise's consumer. For example, what if such an error had actually bubbled from inside a library the consumer is using? Should the consumer's asynchronous flow be interrupted even if he had a catch in place for handling such errors?
I think the burden of making sure asynchronous operations are as easy to debug as synchronous ones lies with the browser / JavaScript engine. Logging unhandled rejections is the most obvious aspect of this but there are plenty of other things that can be done to improve the developer's experience. For example engines could provide the asynchronous call stack when using promises. This is a feature available in the newest Visual Studio 2013 and it supports WinJS promises (http://blogs.msdn.com/b/visualstudioalm/archive/2013/07/01/debugging-asynchronous-code-in-visual-studio-2013-call-stack-enhancements.aspx)
Asking the developer to finish their asynchronous flow with a
done
creates the potential for them to forget to do so just as much as they now forget to finish it with acatch
.domenic commentedon Sep 6, 2013
I agree with everything @mhofman says, with the caveat that I am not sure what the exact solution would be for consoles (i.e. non-interactive debuggers). I would like a solution that does not affect the authoring-time experience, though.
152 remaining items