use a messy loop instead of a deeply nested async fn chain (fix #1523)