-
Notifications
You must be signed in to change notification settings - Fork 2k
Description
From @mitar on 2016-12-12 03:53
I believe CoffeeScript could have a simpler syntax to use async/await. With coffeescript6/discuss#10 and #3757 initial support for that was merged in, but I think more could be done.
Here are some my previous thoughts on the subject, but here I am proposing another iteration of those thoughts.
I see three issues with current async/await and promises state in JavaScript:
- we had callback hell, now we have
new Promise (resolve, reject) =>
hell - having to think which function is async and which is not and then use wait properly (CoffeeScript makes it defining easier by adding
async
keywords automatically to functions if they useawait
, but then it is harder to know when should one call a function withawait
) - have code full of
await
keywords around
To address the point 1. I would suggest the ~>
operator for defining functions which return a promise:
fetch = (url) ~>
request url, (error, response, body) ->
resolve error if error
reject body
Would be compiled into:
var fetch;
fetch = function(url) {
return new Promise(function (resolve, reject) {
request(url, function(error, response, body) {
if (error) {
reject(error);
return;
}
resolve(body);
return;
});
});
};
I am not sure if ~>
should bind this
or not, I think it probably should inside another function, and not for class methods. resolve
and reject
would be forbidden to define by the developer inside ~>
function. Calling resolve
or reject
always returns. If you do not want to do that, you should use new Promise
manually.
If you simply want to create a promise, and not a function which returns a promise, you can do:
google = do ~>
request 'https://www.google.com', (error, response, body) ->
resolve error if error
reject body
So google
now is a promise with content of Google's home page.
The reason why ~>
is a function which returns a promise and not just returns a promise is so that it is clear that it does not call start the promise, but that you have to call it, to start it. But we could also use ~>
as a shorthand for new Promise
only.
Anyway, we still have await
all around the code. For that I suggest we further extend ?
operator. We already use it to be able to say "if this is a function, call it", we can also say "if this is a Promise, await it".
Currently, the following:
fetch?()
Gets compiled into:
if (typeof fetch === "function") {
fetch('https://www.google.com');
}
And I suggest it gets turned into:
var temp;
if (typeof fetch === "function") {
temp = fetch('https://commons.tnode.com');
if (temp && typeof temp.then === "function") {
await temp;
}
}
The side-effect of this change would be that using ?
in a function would make then all functions aync
? Hmm. Maybe we need another symbol for this. But I would love to have a symbol which would call a function as await
with something shorter than await
.
I really think caller should not care how is a function implemented. So that they can just call a function and get the result, async or not.
What would be a drawback of making all functions async?