14

I've recently discovered, and fallen in love with, the Deferred/Promise pattern used in jQuery. It just encapsulates so many async use cases, including the wonderful chaining, filtering ability, that I can't believe I missed it for so long.

I've just finished refactoring my AS3 code to use the excellent CodeCatalyst/promise-as3 library (https://github.com/CodeCatalyst/promise-as3), and so started thinking about going back to my C++ code and seeing how I could implement the pattern there.

Before I started coding this myself, I checked to see if it had been done before, and discovered the std::future/std::promise (and boost equivalents), but they are very heavy (they seem use real threads etc, and have a heavy template syntax).

So, my question is: Is there are lightweight, pure C++ implementation of the Deferred/Promise pattern, jQuery-style?

refs:

4

7 回答 7

14

很抱歉玩死灵法师,但我也对在 C++ 中使用A+风格的 Promise非常感兴趣,并且花了数年时间寻找实现它的最佳方法。我最终成功了,你可以在这里看到我的实现。

用法非常简单,但确实大量使用了模板和模板元编程。这是一个例子:

Promise<int> promise;

promise.future().then([](int i){
    std::cout << "i = " << i << std::endl;
    return "foobar";
}).then([](const std::string& str){
    std::cout << "str = " << str << std::endl;
});

promise.resolve(10);

这将打印出:

i = 10
str = foobar
于 2015-08-15T21:05:33.080 回答
8

我不确定您所追求的解决方案有多轻巧,但是std::async极大地简化了未来/承诺对的设置,并允许调用者决定工作是由另一个线程异步执行还是延迟执行在同一个线程中执行。在任何情况下,调用者都不必进行任何显式的线程管理。

于 2012-07-09T05:21:52.237 回答
6

有几个原因我认为你所要求的在 C++ 中几乎是不可能的。

首先,为了使用C++11 的新 lambda 语法来进行内联函数声明(在 JavaScript 中这等价物是微不足道的且非常轻量级的),您几乎都必须使用模板来使用它们。

其次,与 JavaScript 不同,没有自动的 UI 线程供您将计时器/完成队列停放在上面,因此您几乎必须求助于创建一个线程池来监视准备好执行其任务的任务下一步。

当您说“纯 C++”和“轻量级”(以及隐式无线程)时,您还想到了什么?

于 2012-07-09T05:25:31.440 回答
1

您可以使用协作式多任务处理程序。我在我的应用程序中使用了一个。我遇到的唯一问题是,如果我将 lambda 存储在 list<> 中并稍后调用它,则捕获的变量会被破坏。我还没有找到解决方案,但我很确定应该可以做到这一点。

于 2014-03-23T04:27:16.907 回答
1

我知道这个问题很老,但是我想还有值得一提的rili,它可能完全实现了你想要的。

有一些示例和文档。

与 lifewanted(liblw) 一样,它在很大程度上基于模板。该库的主要功能之一是 A+ Promises 实现 - 包括 Then(单个和两个参数)、Catch 和 finally。

链接:

于 2017-03-20T11:36:13.917 回答
1

这是另一个模仿 JavaScript Promise 的 C++ Promise 库。它被设计为轻量级的,因此它可以用于例如非常 I/O 密集型异步软件,同时具有 JS 所承诺的许多优点。它已经在一个非常受欢迎的项目中使用了多年,因此经过实战证明: https ://github.com/alxvasilev/cpp-promise

于 2020-01-09T18:57:58.643 回答
0

只需使用 Facebook 的 Folly 库:https ://github.com/facebook/folly/blob/master/folly/docs/Futures.md

Boost.Thread 和 C++17(甚至还不支持组合器)提供的功能不如 Folly。在 Folly 中,您甚至可以收到成功的结果,而不是像用户 Oz 的答案中显示的那样尝试。您可以通过使用线程池执行器(这以前是 Wangle 的一部分,但现在是 Folly 的一部分)甚至内联执行器来限制线程数。如果没有模板,您将无法在 C++ 中走得更远,它们确保了类型安全,这是一件好事。

请记住,您必须对期货使用移动语义,但您可以使用 folly::SharedPromise 从一个承诺创建多个期货。

您还可以查看此列表:https ://en.wikipedia.org/wiki/Futures_and_promises#List_of_implementations (“基于非标准库的期货实现:”)。

于 2018-09-27T10:22:33.587 回答