【问题标题】:Javascript stack inspection on Safari Mobile (iPad)Safari Mobile (iPad) 上的 Javascript 堆栈检查
【发布时间】:2011-07-18 13:20:21
【问题描述】:

我的代码如下所示:

function myEventHandler() {
    inMyEventHandler = true;
    longRunningStuff();
    inMyEventHandler = false;
}

这很好用,除了在 iPad 上,Safari Mobile 偶尔会因错误而使我的 Javascript 超时。所以 longRunningStuff() 死了, inMyEventHandler 永远不会被清除。这很糟糕,因为如果我们在这个函数之外,那么 inMyEventHander 绝对不能设置,否则会发生坏事(tm)。

理想情况下,我可以从 longRunningStuff 的深处检查 ​​myEventHandler 是否在调用堆栈中高于它,这会自行解决。我找不到这样做的方法...提示?

【问题讨论】:

标签: javascript ipad mobile-safari


【解决方案1】:

多年来我一直使用以下方法手动检查调用堆栈。我已经有一段时间没有更新它了,也从未在 ipad 或移动 safari 上尝试过,所以我无法判断它是否对你有用。

也许你可以用它来获得灵感:

function logStackTrace(levels) {
    var c = console;
    var callstack = [];
    var isCallstackPopulated = false;
    try {
        throw new Error();
    } catch (e) {
        if (e.stack) { //Firefox
            var lines = e.stack.split('\n');
            for (var i = 0, len = lines.length; i < len; i++) {
                if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
                    callstack.push(lines[i]);
                }
            }
            //Remove call to logStackTrace()
            callstack.shift();
            isCallstackPopulated = true;
        }
        else if (window.opera && e.message) { //Opera
            var lines = e.message.split('\n');
            for (var i = 0, len = lines.length; i < len; i++) {
                if (lines[i].match(/^\s*[A-Za-z0-9\-_\$]+\(/)) {
                    var entry = lines[i];
                    //Append next line also since it has the file info
                    if (lines[i + 1]) {
                        entry += " at " + lines[i + 1];
                        i++;
                    }
                    callstack.push(entry);
                }
            }
            //Remove call to logStackTrace()
            callstack.shift();
            isCallstackPopulated = true;
        }
    }
    if (!isCallstackPopulated) { //IE and Safari
        var currentFunction = arguments.callee.caller;
        while (currentFunction) {
            var fn = currentFunction.toString();
            var fname = fn.substring(fn.indexOf("function") + 8, fn.indexOf("(")) || "anonymous";
            callstack.push(fname);
            currentFunction = currentFunction.caller;
        }
    }
    if (levels) {
        c.log(callstack.slice(0, levels).join('\n'));
    }
    else {
        c.log(callstack.join('\n'));
    }
};

【讨论】:

    【解决方案2】:
    1. (最简单)longRunningStuff时可以查看arguments.callee.caller

      function longRunningStuff() {
        if (arguments.callee.caller === myEventHandler) {
          // take care
        }
      }
      
    2. 另一种变体:

      function myEventHandler() {
        // code
      }
      myEventHandler.disable_in_longRunningStuff = true;
      function longRunningStuff() {
        if (arguments.callee.caller.disable_in_longRunningStuff) {
          // take care
        }
      }
      
    3. 最长的方式——从https://github.com/eriwen/javascript-stacktrace检索调用栈

    【讨论】:

      【解决方案3】:

      从 iOS 6 开始,可以使用真正的网络检查器。见下文,或此链接。 https://stackoverflow.com/a/12762449/72428

      更新!!!在 OS X 上,您可以在 iOS 模拟器和 iOS 6 设备上使用 Safari 网络检查器。

      1. 首先在 Safari 中启用开发者菜单。
      2. 接下来,在您的 iOS 设备(或模拟器)上启用远程调试。

        Settings > Safari > Advanced > Web Inspector (ON)
        
      3. 返回设备上的 Safari。
      4. 返回您的计算机,单击“开发人员”菜单,然后选择您的 设备(例如 iPhone 模拟器、iPhone)

      注意:只有当 Safari 处于活动状态并正在运行时,您才会在开发者菜单中看到您的设备。

      享受吧!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多