Здравствуйте, Videoman, Вы писали:
V> Он не позволяет убрать под капот логику ожидания длительных операций.
Я тут подумал... (со мной такое иногда бывает)
Действительно, при ожидании длительных логика может очень запутываться.
Надо это как-то организовать.
Применим объектный подход.
Так как с прикладной точки зрения основная операция при асинхронном вызове — это операция ожидания, то и создадим объект ожидания, назавём его WaitingBlock.
WaitingBlock должен уметь:
1) начать что-то делать
2) ждать окончания или таймаута
3) по таймауту выполнить одну операцию
4) по окончанию выполнить другую операцию.
выглядеть это должно как-то так:
auto fnConnect = [addr=strUrl]() { return ConnectTo(addr); };
auto fnOnOk = [addr=strUrl](ConnectResult result) { return DoSamthing(addr); };
auto fnOnTimeout = [addr=strUrl]() { std::cout << "timeout"; };
WaitingBlock doWork (std::chrono::seconds(432), fnSendData, fnClose, fnOnTimeout);
WaitingBlock doConnect(std::chrono::seconds(132), fnConnect, doWork, fnOnTimeout);
Это один из подходов.
Другой подход я написал этой осенью.
Этой осенью я написал ftp клиента, который работает по автоматическому сценарию.
Сценарий задаётся в виде последовательности действий ActConnect, ActUser, ActPassword, ActFileDownload, ActFileUpload...
Каждое действие это объект, который, понятно, выполняет одну асинхронную операцию или является специальным, для условных или безусловных переходов.
Есть специальный объект Scenario, в котором задаётся последовательность операций.
При этом, по мере своего выполнения, сам сценарий может изменяться изнутри операции: добавлять или пропускать операции по выгрузке или загрузки файлов.
Но такой подход не использует никаких особых новшеств языка и мог быть написан много лет тому назад.
Так что мне не понятен причём тут C++17 или C++20