处理嵌套回调

时间:2017-11-26 06:28:59

标签: c++ function c++11 callback

我遇到了一个我需要处理嵌套回调的情况。请参阅Thing::process功能。第二个g_thing.onAfterWalk()回调将永远不会被调用,因为父进程将在执行完后立即将其销毁。

Thing g_thing;

void Thing::walk(int32_t x, int32_t y) {
    if (SYSTIME() > m_walkEndTime) {
        // Still walking
        return;
    }

    auto obj = g_thing.localObject();
    auto walkDuration = obj->getWalkDurationTo(x, y);
    [..]
    m_walkEndTime = SYSTIME() + walkDuration;

    [..]

    // Walk finished. Run callback
    if (m_afterWalk) {
        m_afterWalk();
        m_afterWalk = nullptr;
    }
}

void Thing::onAfterWalk(std::function<void(void)>& callback) {
    m_afterWalk = callback;
}

void Thing::process() {
    [..]
    // Store a callback and walk
    g_thing.onAfterWalk([]() {
        // Store another callback
        // After walking to 4321, 4321 do something else.
        // My actual problem... Callback within callback
        g_thing.onAfterWalk([]() { 
            std::cout << "Walking finished.\n";
        });

        // After walking to 1234, 1234 walk to 4321, 4321
        g_thing.walk(4321, 4321);
    });
    g_thing.walk(1234, 1234);
}

如何处理这些嵌套回调?

我是否应该使用回调队列创建std::stack?什么是最好的方法?

1 个答案:

答案 0 :(得分:0)

适合我(有一些调整:constonAfterWalk的参数上,最后是std::cout.flush()。你确定你不仅仅是在stdout中丢失了输出吗?

#include <iostream>
#include <functional>

class Thing;
extern Thing g_thing;

class Thing
{
  std::function<void(void)> m_afterWalk;
public:
  void walk()
  {
    if(m_afterWalk)
    {
      m_afterWalk();
      m_afterWalk = nullptr;
    }
  }

  void onAfterWalk(const std::function<void(void)>& callback)
  {
    m_afterWalk = callback;
  }

  void process()
  {
    // Store a callback and walk
    g_thing.onAfterWalk([]() {
        // Store another callback
        g_thing.onAfterWalk([]() {
            std::cout << "Walking finished.\n";
        });
        g_thing.walk();
    });
    g_thing.walk();
  }
};

Thing g_thing;

int main(int argc, char *argv[])
{
  g_thing.process();
  std::cout.flush();
}

产量

$ g++ -pedantic -Wall -Werror test.cpp
$ ./a.out
Walking finished.