https://namsoocho.github.io/async-book/01_getting_started/04_async_await_primer.html
async/.await 입문 - Asynchronous Programming in Rustasync/.await 입문 - Asynchronous Programming in Rustnamsoocho.github.io// `join!` is like `.await` but can wait for multiple futures concurrently.
// If we're temporarily blocked in the `learn_and_sing` future, the `dance`
// future will take over the current thread. If `dance` becomes blocked,
// `learn_and_sing` can take back over. If both futures are blocked, then
// `async_main` is blocked and will yield to the executor.
1. learn_and_sing에서 await를 만나면 해당 async fn에서 빠져나옴
2. 그 다음 async fn인 dance에 들어가서 돌다가 여기서 await를 만나면 이전 await 위치이자 완료된 leanr_and_sing으로 돌아감
3. sing_song을 실행시키고 await를 만나서 다시 dance로 가서 dance를 완성시키고 f2(dance가 return한 promise)는 join
4. 이후 다시 sing_song이 완료되고 해당 await쪽으로 돌아가 f1(learn_and_sing이 return한 promise)을 join
예전에 이런 개념을 코루틴이라는 개념으로 본 적이 있는거 같은데 다른 언어의 async도 이런식으로 작동함?
러스트의 async 함수는 비동기 루틴을 자동으로 만들어주는 문법일 뿐임. async 함수를 호출하면 impl Future 타입을 반환하는데 이걸 await하거나 tokio같은 실행자에 전달해야 실제로 실행됨. 다른 언어의 async 함수는 호출하는 순간 await하지 않아도 스케줄러에 추가되어서 실행됨.