firebug(1.10.1)建议javascript不限于firefox中的单个线程(13.0)

时间:2012-08-03 20:22:55

标签: javascript multithreading firefox firebug

今天在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中查看控制台选项卡,您应该注意到get请求失败(跨域违规与我试图在这里提出的观点无关),然后你很可能会看到:

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中运行的同一页面,那么两个断点都会像我期望的那样被击中。

3 个答案:

答案 0 :(得分:2)

我认为可以安全地假设您观察到的异常是由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()函数显然需要很长时间才能执行,但控制台仍会在此处反映日志语句的正确顺序。另外值得注意的是,如果插入相同的断点,则排序将无效,就像原始示例一样。

我和Firebug一起file an issue

答案 1 :(得分:0)

$.get("http://google.com/")是异步的,它是对首先完成的事情的竞赛。第一次它变慢,因为它需要进行调用,并且调用稍后在代码执行中发生。该调用已经缓存了第二个请求,因此它更快地执行。

如果您在请求结束前需要完成某些操作,请使用beforeSend()

答案 2 :(得分:0)

根据我的经验,在异步代码中放置断点时,Firebug无法正常工作。

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

在Chrome中,它似乎工作正常(它们以某种方式智能地延迟超时)。也许是因为Chrome开发工具内置于浏览器中,因此操作超时更容易。 Firebug“只是”一个附加组件,也许正确地执行它可能很棘手。

重现问题的简单脚本:

当我将值分配给xyz时,将断点放在行中。 首先,您将在x = 1行上找到一个断点。使用 F10 跳过。只有当你按 F10足够快时,你<{1>} } }上的将不会遇到断点(Firefox 14,Firebug 1.10)。

z = 3