多重延续链:boost.future 展开。怎么做

Ger*_*ago 0 c++ concurrency continuations boost c++11

boost.future<T>在 boost 1.56 中使用了 continuation。

我有一个返回未来的 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) { ... });
Run Code Online (Sandbox Code Playgroud)

也就是说,我有:

  1. future<R>::then
  2. 在第一个延续中,我使用返回 a 的 API 调用从 lambda 返回boost::future<R>,然后我解开它。
  3. 之后我想附加另一个延续,但从未调用过这个延续。

题:

  1. 在第一个延续中这样做是正确的:(return api_returns_future().get()注意我.get()直接从延续内部调用`并放弃解包?。这个替代方案是否对我的代码的异步性有一些缺点?

编辑:我更新了问题以更好地反映经过更多研究后我想问的问题。

谢谢

Bar*_*rry 5

如果您查看boost docs,有一个如何使用的示例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 
});
Run Code Online (Sandbox Code Playgroud)

请注意,then它也将其 lambda 的结果包装在 a 中future。现在在你的情况下,你的 lambda 返回一个未来,所以作为第一次,你必须写:

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

但出于这个原因,文档还指出有一个解包移动构造函数

展开移动构造函数 - EXTENSION

 future( future< future<R>>& other); // EXTENSION
Run Code Online (Sandbox Code Playgroud)

后置条件
this->get_state()返回other->get_state()调用之前的值。other->get_state()返回boost::future_state::uninitialized。关联的共享状态现在已展开,内部未来共享状态与 相关联*thisother不与任何共享状态相关联! other.valid()

因此,我希望您能够编写以下内容:

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

因为图书馆会自己处理解包。