-
Notifications
You must be signed in to change notification settings - Fork 105
Grammar for interfacing existing callback code with async/await #38
Comments
I understand the problem trying to be solved, but I would be -1 on adding additional keywords like |
I don't disagree at all about introducing new keywords - the use of 'asyncReturn' and 'asyncError' was to demonstrate one implementation. In our own code I've re-used The use case is, in my mind, very common. We have quite a lot of code using async/await in production, much of it on top of callback based libraries running on node v0.10 and Chrome. The ability to have a platform/implementation independent mechanism for having a callback cause an async function to respond is very useful. The alternative is each developer assuming certain platform features or wrapping existing functions in one-or-another Promise implementation and testing heavily. |
The future is longer than the past. Promises are standardized and returned from future-facing APIs. Adapting legacy patterns is not something we should build in to the language. |
That's pretty philosophical! I know we have different approaches to development, but this use case is borne out of a lot of effort getting async/await into production (pretty successful so far). It might be a feature of our early adoption, but it will definitely be an issue faced by a lot of developers. I thought it might be worth sharing with the community as having a standardized way of interfacing "the past" to the future eased our path considerably. I prefer to think of it less as "adapting legacy patterns" and more as "helping developers move into the future successfully". |
I'm all about helping developers move into the future successfully! I just don't think that's something the language itself should be responsible for. |
Dominic - you're a very clever guy, and I'm a big fan of your blog and work, but I don't see how that moves things forward. For us mortals, language support for otherwise fiddly constructs (like making async/await different from yield/generators - you made a very good comment on why this is a good thing on https://esdiscuss.org/topic/does-async-await-solve-a-real-problem) is one way to help us. Indeed in that post, you made a convincing case for using the language to do something that could easily be done by a search and replace (although I think it's also a good move for VM providers who can optimize that case separately from the iteration case). You may wish there was no need for this use case, but unfortunately there is. Since we're in the early stages of working out exactly what opportunities and difficulties async and await introduce, maybe it's worth taking on board everyone's experiences and seeing which common cases would benefit from language support? |
It seems to me the concern is actually related to the fact that Promises don't have an external return new Promise(function(resolve,reject) {
setTimeout(resolve,t) ;
}) ; could have been: var d = new Deferred();
setTimeout(d.resolve,t);
return d.promise; IOW, it seems to me like your complaint is needing to wrap the promise constructor function around a piece of code to do the extraction of the resolution capability. Without that requirement, there doesn't seem to be any need for extra syntax of any sort to fake this deep So, just fix that by making your own function Deferred() {
var def = {}, p = new Promise(function(resolve,reject){ def.resolve = resolve, def.reject = reject; });
def.promise = p;
return def;
} Now: async function sleep(t) {
var d = Deferred();
setTimeout(d.resolve,t) ;
return d.promise;
} Of course, when you're only talking about 1-line |
That's certainly a sensible approach. I'm not sure that the extra promise construction and resolution will perform as well as directly resolving the async implementation promise, but I guess it avoids additional syntax, even if it doesn't do such a good job of hiding the implementation details. I'll work through some examples and see how it compares. Thanks for the input |
Agreed with @domenic and @getify that we shouldn't introduce new syntax for these cases. I'm not sure the original code is all that bad for the cases where you need to interface with callback code - especially given that there are so many callback styles in common use that this will have to be somewhat custom per-case anyway. The function sleep(t) {
return new Promise(resolve =>
setTimeout(resolve,t)
);
} async function sleep(t) {
var d = Deferred();
setTimeout(d.resolve,t) ;
return d.promise;
} |
Just a quick clarification: they are similar in a single line function case. In a larger function, where you're indenting dozens of lines of code inside the promise constructor, it's more painful. The pain adds up if there's nested promise creation, etc. Also, the pain is increased if you're dealing with |
Whilst Promises provide an mechanism to relate the (considerable) body of callback-based code with async functions, the syntax is relatively verbose and implementation dependent (i.e. it requires and relies on knowledge of the spawn() function) potentially restricting the possible set of implementations.
This issue suggests a mechanism to minimize the boilerplate needed to interface existing code with async/await by allowing callbacks contained within async functions to resolve and reject their container async functions, and prevent the container resolving automatically on exit without a return or throw.
Consider the code below, which has only 1 functional line (2 including the declaration):
An alternative would be to pass the resolve/reject parameters to the re-written generator with two additional parameters (in this example asyncReturn and asyncThrow), parsing
to
The same translation works for direct calls as well:
...translates to
This can be easily implemented by:
resolver
argument (since this is pointless), and always appending a synchronous return to the wrapped generator body.The rewrite rule now becomes:
...and spawn is updated to:
Syntax:
The use of the identifier
asyncReturn
(andasyncError
) is possibly not wise. Additional rewrites would be required, but preferential syntaxes might be:The text was updated successfully, but these errors were encountered: