Safari Mobile (iPad) 上的 Javascript 堆栈检查

发布于 2024-10-22 20:09:45 字数 447 浏览 1 评论 0原文

我的代码如下所示:

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

这非常有效,但在 iPad 上,Safari Mobile 偶尔会导致我的 Javascript 超时并出现错误。所以 longRunningStuff() 会死掉,而 inMyEventHandler 永远不会被清除。这是非常糟糕的,因为如果我们在这个函数之外,那么 inMyEventHander 绝对不能被设置,或者发生坏事。

理想情况下,我可以从 longRunningStuff 的深处检查 ​​myEventHandler 是否在调用堆栈中位于其上方,并且这会自行处理。我找不到办法做到这一点...提示?

I have code that looks like this:

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

This works great, except on the iPad where Safari Mobile occasionally times out my Javascript with an error. So longRunningStuff() dies and inMyEventHandler never gets cleared. This is very bad, because inMyEventHander absolutely cannot be set if we're outside this function, or Bad Things(tm) happen.

Ideally, I could just check from deep within longRunningStuff whether myEventHandler is above it in the call stack, and this would take care of itself. I can't find a way to do that... Hints?

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

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

发布评论

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

评论(3

烂人 2024-10-29 20:09:45
  1. (最简单)您可以在 longRunningStuff 中检查 arguments.callee.caller

    函数 longRunningStuff() {
      if (arguments.callee.caller === myEventHandler) {
        // 小心
      }
    }
    
  2. 另一个变体:

    函数 myEventHandler() {
      // 代码
    }
    myEventHandler.disable_in_longRunningStuff = true;
    函数 longRunningStuff() {
      if (arguments.callee.caller.disable_in_longRunningStuff) {
        // 小心
      }
    }
    
  3. 最长的方法 - 从 https:/ 检索调用堆栈/github.com/eriwen/javascript-stacktrace

  1. (Simplest) You can check arguments.callee.caller when in longRunningStuff:

    function longRunningStuff() {
      if (arguments.callee.caller === myEventHandler) {
        // take care
      }
    }
    
  2. Another variant:

    function myEventHandler() {
      // code
    }
    myEventHandler.disable_in_longRunningStuff = true;
    function longRunningStuff() {
      if (arguments.callee.caller.disable_in_longRunningStuff) {
        // take care
      }
    }
    
  3. The longest way - retrieve call stack from https://github.com/eriwen/javascript-stacktrace

郁金香雨 2024-10-29 20:09:45

多年来我一直使用以下方法来手动检查调用堆栈。我已经有一段时间没有更新它了,也从未在 ipad 或 mobile 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'));
    }
};

I have used the following method for years to manually inspect the callstack. I haven't updated it in a while and never tried it on ipad or mobile safari, so whether or not it will even work for you i can't tell.

Maybe you can use it for inspiration:

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'));
    }
};
酒绊 2024-10-29 20:09:45

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

更新!!! 在操作系统上X 您可以在 iOS 模拟器和 iOS 6 设备上使用 Safari Web 检查器。

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

    设置>野生动物园>高级>网络检查器(ON)
    
  3. 返回设备上的 Safari。
  4. 返回您的计算机,单击“开发人员”菜单,然后选择您的
    设备(例如 iPhone 模拟器、iPhone)

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

享受!

As of iOS 6 a real web inspector is available. See below, or this link. https://stackoverflow.com/a/12762449/72428

Update!!! On OS X you can use the Safari web inspector on the iOS Simulator AND iOS 6 devices.

  1. First enable the Developer menu in Safari.
  2. Next, enable remote debugging on your iOS device (or simulator).

    Settings > Safari > Advanced > Web Inspector (ON)
    
  3. Go back to Safari on your device.
  4. Go back to your computer, click the Developer menu, and select your
    device (e.g. iPhone Simulator, iPhone)

Note: You'll see your device in the Developer menu ONLY when Safari is active and running.

Enjoy!

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