【问题标题】:firebug (1.10.1) suggests javascript is not confined to a single thread in firefox (13.0)firebug (1.10.1) 建议 javascript 不局限于 firefox (13.0) 中的单个线程
【发布时间】:2012-08-07 04:03:43
【问题描述】:

今天在 Firefox 中调试一些客户端 javascript 时,我遇到了一些我觉得很奇怪且有点令人不安的事情。此外,在使用 IE / VS2010 调试同一脚本时,我无法复制此行为。

我创建了一个简单的示例 html 文档来说明我看到的异常情况。

<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.js" type="text/javascript" ></script>
</head>

<body id="main_body">
    <script type="text/javascript">
        $(function () {
            $(".test-trigger").on("click", function () {
                loadStuff();
                console && console.log && console.log("this will probably happen first.");
            });
        });

        function loadStuff() {
            $.get("http://google.com/")
                .fail(function () {
                    console && console.log && console.log("this will probably happen second.");
                });
            }
    </script>
    <button class="test-trigger">test</button>
</body>
</html>

如果您将此文档加载到 Firefox(我在 Windows 7 上使用版本 13.0 和 Firebug 版本 1.10.1),单击测试,然后在 Firebug 中查看控制台选项卡,您应该注意到获取请求失败(跨域违规与我在这里要说明的观点无关),然后您很可能会看到:

this will probably happen first.
this will probably happen second.

现在,在第 13 行和第 20 行放置断点:

13: console && console.log && console.log("this will probably happen first.");
20: console && console.log && console.log("this will probably happen second.");

如果您再次单击测试,您将按预期中断第 13 行。现在,继续执行。如果您的经验和我一样,您不会在第 20 行中断。此外,如果您切换到控制台选项卡,您将看到以下日志输出序列:

this will probably happen second.
this will probably happen first.

对我来说,这表明 ajax 请求的失败处理程序正在一个线程中执行,而不是在其中执行单击处理程序的线程中。我一直被引导相信单个页面的所有 javascript 将由任何浏览器中的单个线程执行。我在这里错过了一些非常明显的东西吗?感谢您对此观察的任何见解。

哦,如果我使用 Visual Studio 调试在 IE 中运行的同一个页面,两个断点都会按预期命中。

【问题讨论】:

  • $.get 函数正在执行异步 ajax 查询。调用失败回调的速度取决于浏览器从 google.com 听到的速度。如果它足够快,它会在调用 console.log 函数之前进入。不足以判断它是否是线程的。
  • 如果您的预期行为出现在浏览器中,那么长的 ajax 查询会使网页无法使用。
  • 我在这里真正要问的是为什么在 firebug 中调试时不会同时访问第 13 行和第 20 行设置的断点。我不关心行的执行顺序。
  • 你可以在 Ajax 回调中设置一个无限循环,看看会发生什么......

标签: javascript multithreading firefox firebug


【解决方案1】:

我认为可以安全地假设您观察到的异常是由 Firebug 如何实现断点/在幕后工作引起的。不过我无法确认。 OS X 上的 FF 14 也会发生这种情况。

除非 jQuery 立即执行您的 fail() 函数并超过整个 XMLHttpRequest 对象,否则 保证语句的顺序将是 this will probably happen first. 然后是 this will probably happen second.

鉴于 JavaScript 的单线程特性,函数本质上是原子的;他们不会被回调打断。

您似乎在尝试模拟如果click 函数在调用loadStuff() 后需要一段时间才能完成执行时会发生什么。 click 函数不应该fail 方法的执行打断(想想你找到了一种方法来实现这一点)。

为了消除等式中的断点,这里有一个修改版本。标记的其余部分保持不变。

$(function () {
    $(".test-trigger").on("click", function () {
        loadStuff();
        for (var i = 0; i < 1000000000; i++)
        {
            //block for some interesting calculation or something
        }
        console && console.log && console.log("this will probably happen first.");
    });
});

function loadStuff() {
    $.get("http://google.com/")
        .fail(function () {
            console && console.log && console.log("this will probably happen second.");
        });
    }

click 函数在调用loadStuff() 之后显然需要很长时间才能执行,但是控制台仍然会在此处反映日志语句的正确顺序。另外值得注意的是,如果插入相同的断点,则排序将无效,就像原始示例一样。

我希望 file an issue 使用 Firebug。

【讨论】:

    【解决方案2】:

    $.get("http://google.com/") 是异步的,它是先完成什么的竞赛。第一次比较慢,因为它需要进行调用,并且调用发生在代码执行的后期。该调用已与第二个请求一起缓存,因此它执行得更快。

    如果您需要在请求发出之前完成某些事情,请使用beforeSend()

    【讨论】:

    • 我意识到 ajax 调用是异步的,并且不能保证哪一行(13 或 20)将首先执行,但事实上我并没有在第 13 行和第 20 行中断(即使它们都在执行)是我关心的问题。
    【解决方案3】:

    根据我的经验,Firebug 在异步代码中放置断点时效果不佳。

    即如果你有一条直线执行并在其中放置断点,你会没事的。但是,如果您引入异步性,例如通过使用setTimeout,您不会在“并行”行中遇到断点(这当然不是真正的并行,JS 引擎会在任务之间切换)。在过去的几个月里,我经历了很多。

    在 Chrome 中,它似乎运行良好(它们以某种方式智能地延迟超时)。也许是因为 Chrome 开发工具是内置在浏览器中的,所以更容易操作超时。 Firebug “只是”一个附加组件,可能很难正确地做到这一点。

    重现问题的简单脚本:

    当我为xyz 赋值时,在行中放置断点。 首先,您将在x = 1 行中找到一个断点。使用 F10 跳过。 不会在z = 3 的行上遇到断点 将在z = 3 的行上遇到断点,前提是您足够快地按F10 (Firefox 14、Firebug 1.10)。

    <!DOCTYPE html>
    <html>
    <body>
    
    <script type="text/javascript">
    function foo(){
       var x = 1;
       setTimeout(bar, 2000);
       var y = 2;
    }
    
    function bar(){
       var z = 3;
    }
    
    foo();
    </script>
    
    </body>
    </html>
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-01-18
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多