Многократное продолжение цепочки: boost.future unwrapping. Как это сделать

я использую boost.future<T> с продолжениями, в бусте 1.56.

У меня есть API, который возвращает будущее, которое я хочу использовать изнутри
продолжение. Так что в теории мне нужно .unwrap будущее, прежде чем приковать
Второе продолжение.

Поэтому я делаю следующее:

auto result = api_returns_future().then([](boost::future<R> && result) {
do_something_with_result();

//Note I could call .get() here, but I don't
return api_returns_future();
}).unwrap() //Now I unwrap the future here
.then([](boost::future<R> && result) { ... });

А именно у меня есть:

  1. future<R>::then
  2. В первом продолжении я возвращаюсь из лямбды с вызовом API, который возвращает boost::future<R> и позже я разворачиваю это.
  3. После этого я хочу прикрепить еще одно продолжение, но это продолжение никогда не называется.

Вопрос:

  1. Было бы правильно сделать это в первом продолжении: return api_returns_future().get() (обратите внимание, я звоню .get() изнутри продолжение прямо` и отказаться от распаковки ?. Есть ли у этой альтернативы некоторый недостаток асинхронности моего кода?

РЕДАКТИРОВАТЬ: я обновил вопрос, чтобы лучше отразить то, что я хочу спросить после некоторого дополнительного исследования.

Спасибо

0

Решение

Если вы посмотрите в повысить документы, есть пример того, как использовать then():

future<int> f1 = async([]() { return 123; });
future<string> f2 = f1.then([](future<int> f) {
return f.get().to_string(); // here .get() won't block
});

Обратите внимание, что then оборачивает результат своей лямбды в future тоже. Теперь, в вашем случае, ваша лямбда возвращает будущее, поэтому для начала вам нужно написать:

auto result = api_returns_future().then([](future<R> result) {
// stuff
return api_returns_future();
}).then([](future<future<R>> result2) {
//         ^^^^^^^^^^^^^^^^^
// other stuff
});

Но по этой причине документы также указывают, что существует развернуть переместить конструктор:

Развернуть Move Constructor — РАСШИРЕНИЕ

 future( future< future<R>>& other); // EXTENSION

Постусловия
this->get_state() возвращает значение other->get_state() до звонка. other->get_state() возвращается boost::future_state::uninitialized, Связанное общее состояние теперь развернуто, и внутреннее будущее общее состояние связано с *this, other не связан ни с каким общим состоянием, ! other.valid(),

Таким образом, я ожидаю, что вы сможете написать следующее:

auto result = api_returns_future().then([](future<R> result) {
// stuff
return api_returns_future();
}).then([](future<R> result2) {
//         ^^^^^^^^^
// other stuff
});

поскольку библиотека сама позаботится о распаковке.

4

Другие решения