处理嵌套回调

Dealing with nested callbacks

本文关键字:回调 嵌套 处理      更新时间:2023-10-16

我遇到了我需要处理嵌套回调的情况。请参阅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吗?最好的方法是什么?

对我有用(对param至 onAfterWalk进行了一些调整: const,最后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.