Как решить вопрос ожидания в асинхронном программировании?
Тут проблема не в асинхронном коде, а в том что обработка ваших данных занимает слишком много времени. Если бы у вас обработка данных была синхронной - была бы та же проблема.

Таким образом, у вас 2 варианта:
1. Увеличить таймаут на nginx (или кто там отвечает 502 Gateway timeout), чтобы он ждал ответа 10 минут. Пользователю при этом тоже придется ждать. На фронте в это время можно рисовать "крутилку" или запустить прямо в браузере тетрис :)
2. Делать общение с фронтом асинхронным тоже. Пользователь загружает файл, файл уходит в обработку и фронту сразу же возвращается 200 OK + идентификатор задачи. Фронт с определенной периодичностью (10-30 секунд) опрашивает по идентификатору бэк "ну что, закончилась обработка?". И как только закончилась - бэк ему отдает итоговый файл. Пока обработка не закончилась - бэк может отдавать данные о количестве обработанных записей, что позволит фронту рисовать прогресс-бар, например.
2а. Тоже самое что и в п.2, но уведомление о завершении задачи посылает бэк через WebSocket.
Нужно реализовать асинхронное выполнение и на стороне пользователя тоже.
Сделайте что-то типа "заданий".
Пользователь загружает файл - создается "задание". Пользователь может зайти в какой-то список заданий и посмотреть их прогресс. Когда задание выполнено - пользователь должен получить возможность выгрузить результаты.