| Edited because I didn't realize how old the article is. Almost everything the article says about C# is wrong: > Sync functions are just called, async ones need an await. No they don't. An async method can be called like any other method and you'll just get the Task<T> object. > You can’t unwrap it unless you make your function async and await it. False. You can just access .Result and it'll execute synchronously. > Before they added async-await and all of the Task<T> stuff, you just used regular sync API calls. You can still call the sync APIs, and I'm not getting any impression that those APIs are unmaintained or that they're avoiding adding new ones where it makes sense, even if in many cases it's literally just a matter of calling the async method and accessing .Result! When they describe how the compiler transforms async code into closures, they seem to get this right, but for some reason they treat it as a problem and I can't figure out why. The compiler transformation is exactly the right tool for the job. They even mention the great benefit of it not needing special runtime support. I'm very confused as to the direction of this argument. By the way, while I was reading the first part, before the “big reveal”, my two top guesses for what it's about were C++ const correctness, and Java checked exceptions. I'd argue that more of their arguments apply to those than to async/await. |
function foo(cb) { cb(42, null) }
or
function foo() { return new Promise((resolve, reject) =>{ resolve(42) }) }
the second allowed for .then and .catch
foo.then((value) => console.log(value)).catch((error) => // handler error)
which isn't much better but did get us chaining
foo().then((v) => bar(v)).then((v) => baz(v)).catch()