How to avoid the callback hell when using the new core:nio?

When using the new core:nio how can I prevent the callback hell that occurred at the Javascript community? I know Odin doesn’t have a runtime like Go, so things like Goroutines are not possible. But there is anything that I could do or use to get that feeling of synchronous code that execute IO asynchronous behind the scenes like in Go?

Here’s the thing, any async IO will have stuff executing behind the scenes anyway. There’s no real way around that really.

Without a heavy runtime the choice for async io was either a result queue or callbacks.

Bill ended up picking the callback system (implemented behind the scenes by polling a queue during the tick/run/run_until function calls…).

I personally would have preferred if the queue was available. But I’m not going to be able to change his mind. Instead you can use the no callbacks example which pushes the operation results to a separate queue that you manage.

But as a style choice you can write the code as if it was async/await and then split it into functions at each of the yield points. That way it still mostly looks like sequential code.

You avoid async callback hell by doing simpler things in your callbacks and avoiding thinking in terms of sequences of async operations. If you avoid making IO calls as much as possible from your callbacks, they don’t have the chance to explode into callback hell. You can put things in a queue, mark data as available in some struct you’re checking later in your game loop, etc…

Callback hell happens in Javascript because you don’t control the event loop and all interactivity and IO happens on the event loop. It’s your only tool for doing basically anything, so naturally you’re going to have long chains of callbacks such that you really need await to make you not want to gouge out your eyes from making the code equivalent of a turducken.

I think you’re wanting something like coroutines. They’re certainly implementable using the sync primitives. That’d be a great learning project for anyone unfamiliar.

Am I missing something here? Userspace coroutines aren’t exactly an easy thing to implement, as they require being able to suspend a stack frame and resume it later. I don’t know of any way to do it that doesn’t drop down into calling-convention-aware assembly or something like longjmp to save the whole stack. And then you’re opening a whole can of worms with memory and resource cleanup since defers aren’t going to work as expected.