proper async flow control (still think it's ugly)