Async/await and Tasks in Unity. They basically work similar to Coroutines, but without the boilerplate code required.
I'd even say that Tasks and async is better in most of the cases you'd use a coroutine for - the main difference is that Coroutine is tied to framerate, and is guaranteed to be executed every frame (unless you yield something that waits longer), which is something you can't do with Tasks. But most of my Coroutine usage is tied to WaitForSeconds, and that's where Tasks are IMO better suited.