在jQuery处理程序中抛出异常时,调用堆栈将丢失

Dan*_*don 12 debugging jquery callstack exception-handling exception

我在调试我的Web应用程序时遇到问题.这是非常令人沮丧的,因为我一直试图通过一个小网页重现问题,我可以在jsfiddle上发布,但这似乎是"希格斯 - 布格森"的情况.

我有一个带有大型jQuery(document).ready()处理程序的网页.问题是当从jQuery(document).ready()处理程序中抛出异常时,我得到一个带有几个匿名函数的调用堆栈,并且没有指向实际抛出异常的代码的指针.

每当我尝试用一​​个小网页重现这种行为时,我总是得到一个指向抛出异常的代码的指针,但在生产代码中,我从来没有得到堆栈指针.这使得调试更令人沮丧且容易出错.

有没有人知道什么可能导致这种行为以及如何使它正确?


更新:我发布这个问题已有几个月了,我现在相信我已经最终重现了这个问题.我用以下HTML重现了这个问题:

<html xmlns="http://www.w3.org/1999/xhtml" >    
<body>
Factorial Page
<input type='button' value='Factorial' id='btnFactorial' />
<script src="Scripts/jquery-1.6.1.js" type="text/javascript"></script>
<script type='text/javascript'>
    $(document).ready(documentReady);

    function documentReady() {
        $('#btnFactorial').click(btnFactorial_click);

        factorial(-1);
    }

    function btnFactorial_click() {
        var x;
        x = prompt('Enter a number to compute factorial for.', '');
        alert(x + '! = ' + factorial(x));
    }

    function factorial(x) {
        if (x < 0)
            throw new Error('factorial function doesn\'t support negative numbers');
        else if (x === 0 || x === 1)
            return 1;
        else
            return factorial(x - 1) * x;
    }
</script>       
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

查看代码,您会看到当您单击按钮时,代码会警告您指定的数字的阶乘.输入负数,将产生错误.在这种情况下,Visual Studio将捕获错误并突出显示发生错误的代码行,并显示包含factorial和的调用堆栈btnFactorial_click.

此代码也factorial(-1)从$(document).ready处理程序调用.在这种情况下,Visual Studio将突出显示移动到以下jQuery代码中的finally块(摘自jquery-1.6.1.js,从第987行开始)

            // resolve with given context and args
            resolveWith: function( context, args ) {
                if ( !cancelled && !fired && !firing ) {
                    // make sure args are available (#8421)
                    args = args || [];
                    firing = 1;
                    try {
                        while( callbacks[ 0 ] ) {
                            callbacks.shift().apply( context, args );
                        }
                    }
                    finally {
                        fired = [ context, args ];
                        firing = 0;
                    }
                }
                return this;
            },
Run Code Online (Sandbox Code Playgroud)

虽然未显示调用堆栈,但Visual Studio会显示一个弹出窗口,显示错误的文本.

这种奇怪的行为是什么原因,我如何设计我的应用程序,以便我可以轻松捕获源自处理程序的错误,如$(document).ready?

sea*_*tes 2

我建议创建一个在jQuery(document).ready()块内实例化的对象。例如:

var oStart = function(){
    var pageMethod = function(){ /*...*/ }
    var pageMethodOther = function(){ /*...*/ }
    /*...*/
    var init = function(){
        jQuery(document).ready(function(){
            /* do your stuff here */
        });
    }
}

oStart.init();
Run Code Online (Sandbox Code Playgroud)

这将帮助您将应用程序逻辑和纯 jQuery 逻辑分开。你的准备块中应该只有很少的东西。仅那些在 DOM 完全加载后绝对必要的东西。当页面仍在渲染时,其他所有内容都应该能够加载到内存中。