I argue CSP is far superior to async/await in almost all cases. In Go errors are explicit and always right there. No weird control flow like you see in javascript.
I like a combination of both: actor model high level (basically, the business needs to understand the purpose/meaning of every actor) and then structured concurrency within each actor.
I've been trying to convince the gleam folks of that without too much success so far...
Whenever I used channels in Go, I regretted it at the end. Always have to look up "what happens when I do x and the channel is closed" kind of stuff. Code becomes weird with all the selects and shit.
Yeah, where I worked we rarely used channels directly in business logic. Most of our code looked like "do 5 different time consuming operations, some of them optional i.e can fail" and then combine them all appropriately depending on success/failure so we simply made a BoundedWaitGroup primitive using sync.WaitGroup and a channel to ensure the boundedness that gets used everywhere.
Personally though I prefer either the actor model or structured concurrency to CSP, depending on the usecase.