快速查找函数回调的方法...

发布于 2024-11-27 03:05:38 字数 1397 浏览 4 评论 0原文

我习惯了更多事件驱动的环境,但我现在工作的副本将所有内容都作为函数回调。当我问到这个问题时,一位开发人员说这是因为由于冒泡,回调速度更快,但是冒泡属性总是可以设置为 false...

所以我遇到了试图找出哪个回调函数正在被执行的问题 。参考。

例如:

public class A {
    public function A(){}
    public function func_1():Number{ return 1; }
    public function func_2():Number{ return 2; }
    public function doSomething:Function{ 
        if( Math.random > 0.5 ) return func_1; else return func_2;
    }
}

然后我可能会运行 B 类中的代码:

public class B{
    public var a:A = new A();
    private var action:Function;
    public function B(){ action = a.doSomenthing(); }
}

因此,当我在 BI get action = Function (@34567) 中放置一个断点时,这实际上完全没用...我意识到我可以在 func_1 和 func_1 中都放置一个断点func_2 但我只是将其用作一般示例,代码中散布着函数回调...有没有办法通过内存地址获取函数的名称?谢谢,

我想我明白你所说的堆栈跟踪。但您必须实际单步跳过代码中的函数。在下面的示例中,我必须在回调()上放置一个断点;并跨过它以查看堆栈跟踪更新。问题是我想在调用回调之前知道它们。有时他们在其他地方也被称为。有没有其他方法可以获取回调?

public var callbacks:Array = [];
public function loadURL( url:String, callback:Function ){
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
    callbacks.push( callback );
    var request:URLRequest = new URLRequest(url);
    loader.load(request);
}

public function completeHandler( event:Event ):void
{
    for( var i:int = 0; i < callbacks.length; i ++ ){
        var callback:Function = callbacks[i];
        callback();
    }
}

I'm used to a more event driven environment but the copy I'm working at now dose everything as function call backs. When I asked about this one of the devs said it was because callbacks are faster because of bubbling, but the bubbling property could always be set to false...

So I'm having the problem of trying to figure out which callback function is being referenced.

For example:

public class A {
    public function A(){}
    public function func_1():Number{ return 1; }
    public function func_2():Number{ return 2; }
    public function doSomething:Function{ 
        if( Math.random > 0.5 ) return func_1; else return func_2;
    }
}

Then I might run the code in class B:

public class B{
    public var a:A = new A();
    private var action:Function;
    public function B(){ action = a.doSomenthing(); }
}

So when I put a break point inside B I get action = Function (@34567) which is really completely useless... I realize I could put a break point in both func_1 and func_2 but I'm just using this as a general example there are function callbacks sprinkled through out the code... is there a way to get the name of a function by memory address? Thanks

I guess I see what you are saying about the stack trace. But you have to physically step over the function in the code. In this example below I'd have to put a break point on callback(); and step over it to see the stack trace update. The issue is I want to know the callbacks before they are called. Sometimes they are called in other places. There is no other way to get the callback?

public var callbacks:Array = [];
public function loadURL( url:String, callback:Function ){
    loader.contentLoaderInfo.addEventListener(Event.COMPLETE, completeHandler);
    callbacks.push( callback );
    var request:URLRequest = new URLRequest(url);
    loader.load(request);
}

public function completeHandler( event:Event ):void
{
    for( var i:int = 0; i < callbacks.length; i ++ ){
        var callback:Function = callbacks[i];
        callback();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

羁拥 2024-12-04 03:05:38

这是令人难以置信的古怪代码,但为了这个示例,您可以使用调试器中的调用堆栈:

在此处输入图像描述

您的示例代码有很多问题,但此捕获基于对您的实现的细微调整:

package
{
    import flash.display.Sprite;

    public class MultiCallback extends Sprite
    {
        public function MultiCallback()
        {
            super();

            var b:B = new B();
            b.action()();
        }
    }
}


internal class A
{
    public function A()
    {
    }

    public function func_1():Number
    {
        return 1;
    }

    public function func_2():Number
    {
        return 2;
    }

    public function doSomething():Function
    {
        if (Math.random() > 0.5)
            return func_1;
        else
            return func_2;
    }
}

internal class B
{
    public var a:A = new A();

    public var action:Function;

    public function B()
    {
        action = a.doSomething;
    }
}

This is incredibly wonky code, but for the sake of this example you can use the call stack from the debugger:

enter image description here

Your example code had many issues, but this capture is based upon minor tweaks to your implementation:

package
{
    import flash.display.Sprite;

    public class MultiCallback extends Sprite
    {
        public function MultiCallback()
        {
            super();

            var b:B = new B();
            b.action()();
        }
    }
}


internal class A
{
    public function A()
    {
    }

    public function func_1():Number
    {
        return 1;
    }

    public function func_2():Number
    {
        return 2;
    }

    public function doSomething():Function
    {
        if (Math.random() > 0.5)
            return func_1;
        else
            return func_2;
    }
}

internal class B
{
    public var a:A = new A();

    public var action:Function;

    public function B()
    {
        action = a.doSomething;
    }
}
_畞蕅 2024-12-04 03:05:38

您可以在 try...catch 中抛出错误,以便可以在不终止应用程序的情况下检查堆栈。这个解决方案让我感到畏缩,但同时又非常狡猾。最初由 Ralf Bokelberk 撰写,但由于他的博客目前无法使用 我会链接到这里,这是我找到它的地方。

这是后代代码中的技术:

var stackTrace:String;

try { throw new Error(); }
catch ( e: Error ) { stackTrace = e.getStackTrace(); }

var lines:Array = stackTrace.split('\n');
var isDebug Boolean = (lines[int(1)] as String).indexOf('[') != int(-1);

var path:String;
var line:int = -1;

if (isDebug) {
    var regex:RegExp = /at\x20(.+?)\[(.+?)\]/i;
    var matches:Array = regex.exec(lines[int(2)]);

    path = matches[int(1)];

    //file:line = matches[2]
    line = matches[int(2)].split(':')[int(2)];//windows == 2 because of drive:\
} else {
    path = (lines[int(2)] as String).substring(4);
}

You can throw an error inside a try...catch so that you can inspect the stack without killing the application. This solution makes me cringe, but at the same time it's quite cunning. Originally by Ralf Bokelberk, but since his blog currently doesn't work I'll link to here instead, which is where I found it.

And here is the technique in code for posterity:

var stackTrace:String;

try { throw new Error(); }
catch ( e: Error ) { stackTrace = e.getStackTrace(); }

var lines:Array = stackTrace.split('\n');
var isDebug Boolean = (lines[int(1)] as String).indexOf('[') != int(-1);

var path:String;
var line:int = -1;

if (isDebug) {
    var regex:RegExp = /at\x20(.+?)\[(.+?)\]/i;
    var matches:Array = regex.exec(lines[int(2)]);

    path = matches[int(1)];

    //file:line = matches[2]
    line = matches[int(2)].split(':')[int(2)];//windows == 2 because of drive:\
} else {
    path = (lines[int(2)] as String).substring(4);
}
屋檐 2024-12-04 03:05:38

伙计,我在同一条船上。这个代码库很大并且是以同样的方式完成的。对我来说,“洒”是一个轻描淡写的说法。如果函数对象没有函数名称处理程序,那么您就是 SOL。我理解代码的方法之一是使用 UML 来表示这些不同的类,并使用关联运算符来表明这是在调用某些东西。当回调正在回调另一个回调时,很容易迷失方向。制作 UML 图就像试图让自己摆脱兔子洞的面包屑一样。过了一段时间,你就习惯了。我会采用这种编程方式吗?天哪,不,他们只是让下一个人更难维持。我使用 Violet UML 通过回调来跟踪我的旅程。

Man i am in the same boat. This code base is huge and done in the same way. "Sprinkled" would be an understatement in my case. If a function object has no function name handler, you are SOL. One of the ways for me to comprehend my way through the code was to use UML to represent this different classes and use the association operator to show this is calling something. It's so easy to get lost when callbacks are calling back another callback. Having a UML Diagram that you make is like bread crumbs trying to get yourself out of the rabbit hole. After a while, you get used to it. Would I adopt this way of programming? Hells no, they just made it harder for the next guy to maintain. I use Violet UML to track my journey through the callbacks.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文