xhawk18 / promise-cpp

C++ promise/A+ library in Javascript style.
MIT License
672 stars 92 forks source link

Subsequent calls to `then` on a promise::Defer instance don't work #3

Open shtaif opened 6 years ago

shtaif commented 6 years ago

Thank you for bringing this promise concept to C++ land! This library is super-useful for event loop driven programming! :)

Consider this:

promise::Defer p = promise::resolve();
p.then([]() { std::cout << "THEN 1" << std::endl; });
p.then([]() { std::cout << "THEN 2" << std::endl; });

It appears that "THEN 2" will not be printed. Does the library cannot attach multiple then callbacks such as possible in JavaScript promises?

Thanks in advance! :)

xhawk18 commented 6 years ago

Hi, shtaif, thank you for liking this library.

multiple then is not suppored currently. We can use the below code as a workaround --

    Defer p = promise::resolve();

    p.then([](){
        promise::resolve().then([]() { std::cout << 1 << std::endl; });
        promise::resolve().then([]() { std::cout << 2 << std::endl; });
    });
Akimotorakiyu commented 5 years ago

@xhawk18 恕我愚钝,这两个写法不是等价的吗?看起来是一样的鸭!

xhawk18 commented 5 years ago

@xhawk18 恕我愚钝,这两个写法不是等价的吗?看起来是一样的鸭!

shtaif的写法原本也可以支持的。基于一点微妙的原因,没有支持 ---

promise对象实际上可以包含任意类型的数据,以便交给下一级then调用。 如下的例子里,包含了一个 std::shared_ptr 类型的数据data。

Defer p = promise::resolve().then([](){
       std::shared_ptr<int> data = std::make_shared<int>();
       *data = 3;
       return data;
});

data何时被释放,有两个实现方法: 方法一:p对象被析构时,再释放。 方法二:调用p对象的下一级then时释放。

目前使用方法二,该方法不能达到shtaif要求的效果 -- 在同一个promise对象上调用多个then。因为很明显,调用第二次then,data对象已经被释放,没法传给第二次then函数。

使用方法一,可以达到shtaif要求的效果。带来的问题是 -- promise对象里面的数据,如果反向引用了promise对象本身,则循环引用,造成内存泄漏。这个问题在没有垃圾收集的环境下几乎无解。两相其害权其轻,智能用方法二了。

Akimotorakiyu commented 5 years ago

@xhawk18 明白了。 但是我觉得,既然用了C++,那么内存管理就是开发者自己的锅,框架无需要帮开发者处理内存泄漏的锅! 如果有循环引用也是一样,那应该是开发者的设计漏洞鸭。

xhawk18 commented 3 years ago

The bug was fixed in the latest version, (please use promise::Promise instead of promise::Defer as the return type)

    promise::Promise p = promise::resolve();
    p.then([]() { std::cout << "THEN 1" << std::endl; });
    p.then([]() { std::cout << "THEN 2" << std::endl; });