I've been writing Elixir at work for a few weeks. Yesterday I dove into a friends JS codebase and immediately got confused by the async stuff. While I used to write JS full time, the past 6 months I've spent in Elixir-land has really spoiled me.
I haven't written a lot of
async/await code. It's supposed to be simpler than Promises which are also simpler than callback-soup.
Getting to know Joe
For the past few weeks, I've been starting my day with coffee and reading through Joe Armstrong's old blog. I thought to myself: If I'm going to be writing Elixir, surely I should get to know Joe a little bit better, (if all I can do that through is his blog).
A few days ago I stumbled across the post Red and Green Callbacks and I must say, it has made me feel a little less alone in how confusing JS can be. Let me quote a whole chunk of the article:
var ; var ; ... ... more code ...
Code like this melts my brain.
When the program is executing somewhere inside
more code, the read completes, and I'm time warped back in time to the code in
done, then back to wherever I came from in
donecompletes. I find this very difficult to understand.
Granted, if I understand the post correctly, Joe is mostly talking about the challenge of reasoning about callbacks, whereas I'm complaining about having to write it again, and being a bit confused about the syntax. The fact that Joe, the creator of a complex language and ecosystem has his brain melted by callbacks certainly makes me feel less alone about the whole thing. So, in the spirit of that, I might as well write something I don't understand at the moment.
Async to Async to Async
Here's an example that confuses me (and I could be missing something totally obvious). Note in the codeblock that comments denote the file name.
// api.js // store.js // my_component.js // ... //.. return
In the above code, working backward we have the following happen:
- User clicks component, an async function fires, which awaits
storeDeleteWorkoutcalls the api, awaiting it's function
api.deleteWorkout, when it resolves, returns an object with the shape of
What I find confusing is the train of
async functions. If I'm understanding async/await, any function that calls an async function itself too has to be async. I guess that makes more sense when writing it out. But what if the code in the
store needs to do something to the applications store data based on the result - the promise needs to be resolve
then and there, and have the result do something to the store?
I guess it doesn't matter so much, because in this application we're using a reactive framework - and updating the store would just trickle the effects out to the children of the application.
In the land of elixirs...
I don't quite get what Joe means by Erlang having green callbacks, yet, but that might click in some time. All I know is that I don't have to write red callbacks in Elixir; that I can send messages to processes. I know there is a Task async / await functionality in Elixir, but I honestly won't really grok it until I use it (that's just how the ol' thinker works for me).
It's funny, I've been programming professionally for about 6 years now and concurrency/parallelism still confuses me. But that's also partially because the curious-cat in me wants to know more about what's happening behind the scenes; (ex: how do scheduler's work? How are .)
And no, I'm not asking you to explain it to me! I'll figure it out the way my mind was meant to figure it out in time. For me, that just means rinse and repeat, and a little bit of studying and writing blog posts when I feel like it :)