多个连续链接:boost.future展开。怎么做

时间:2015-01-23 04:33:50

标签: c++ c++11 boost concurrency continuations

我正在使用boost.future<T>继续,在boost 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. 在第一个延续中,我从lambda返回一个返回boost::future<R>的API调用,之后我将其解包。
  3. 之后我想附加另一个延续,但是从未调用此延续。
  4. 问题:

    1. 在第一个延续中执行此操作是正确的:return api_returns_future().get()(注意我直接从延续内部调用.get()并放弃展开?。这个替代方案对异步性有一些缺点吗?我的代码?
    2. 编辑:我更新了这个问题,以便更好地反映一些更多研究后我想要问的内容。

      由于

1 个答案:

答案 0 :(得分:4)

如果您查看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 
});

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

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

但出于这个原因,文档还表明存在unwrap 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
});

因为图书馆将负责展开本身。