如果前面的脚本失败,则执行或不执行 JavaScript 片段

标签 javascript jquery error-handling jquery-events

我刚刚了解到一个关于在抛出错误时执行 Javascript 的重要事实。在我开始对此下结论之前,我最好验证一下我是否正确。
给定一个包含 2 个脚本的 HTML 页面:

<script src="script1.js" />
<script src="script2.js" />
脚本1:
doSomething();
脚本2:
doSomeOtherThing();
这有效地导致将单个脚本作为一个单元进行处理:
doSomething();
doSomeOtherThing();
特别是,如果 doSomething抛出错误,执行被破坏。 'script2' 永远不会被执行。
这是我的 “第一课” - 人们可能会认为,因为它是一个单独包含的文件,所以它不受 script1 的影响。但它是。 => 请参阅下面的“延迟更新”

现在,如果我们按如下方式更改 script2(假设我们在上面的某处包含了 jQuery):
$(document).ready({ doSomeOtherThing(); });
并将脚本放在 script2 之前:
<script src="script2.js" />
<script src="script1.js" />
执行顺序实际上仍然是“doSomething()”之后(有时)是“doSomeOtherThing()”。
然而,它是在两个“单元”中执行的:
  • doSomething作为文档的 java 脚本的一部分提前执行
  • doSomeOtherThing在处理 document.ready 事件时执行。

  • doSomeOtherThing抛出异常,它会 不是 打破第二个处理“单元”。
    (我避免使用术语 thread 因为我认为所有脚本通常都由同一个线程执行,或者更准确地说,这可能取决于浏览器。)
    所以,我的 第 2 课 :即使 JavaScript 错误可能会阻止任何后续脚本执行,它也不会停止事件循环。

    结论 1 $(document).ready()在定义应该独立于任何其他脚本执行的 JavaScript 代码块方面做得很好。
    或者,换句话说:如果你有一段 JavaScript 并且想要确保即使其他脚本失败也能执行它,请将它放在 $(document).ready() 中。 .
    这对我来说是新的,因为如果脚本依赖于完全加载的文档,我只会使用该事件。

    结论 2
    更进一步,将所有脚本包装在 $(document).ready() 中可能是一个很好的架构决策。确保所有脚本都“排队”执行。在上面的第二个例子中,如果 script2.js被包含在 script1.js 之后如示例 1 所示:
    <script src="script1.js" />
    <script src="script2.js" />
    
    script1.js 中的错误会阻止 doSomeOtherThing()甚至被注册,因为$(document).ready()函数不会被执行。
    但是,如果 script1.js 使用 $(document).ready() ,这也不会发生:
    $(document).ready(function() { doSomething(); });
    $(document).ready(function() { doSomeOtherThing(); });
    
    两行都将被执行。然后事件循环将执行 doSomething哪个会坏,但是 doSomeOtherThing不会受到影响。
    这样做的另一个原因是渲染页面的线程可以尽快返回,并且可以使用事件循环来触发代码执行。

    批评/问题:
  • 我弄错了吗?
  • 有什么原因需要立即执行一段代码,即不将其包装到事件中?
  • 它会显着影响性能吗?
  • 是否有另一种/更好的方法来实现相同的目标而不是使用文档就绪事件?
  • 如果所有脚本都将其代码注册为事件处理程序,是否可以定义脚本的执行顺序?事件处理程序是否按照注册的顺序执行?

  • 期待任何有用的评论!
    晚更新:
    就像 Briguy37 正确指出的那样,我的观察首先肯定是错误的。 (“我错了 - 是的!”)。以他的简单示例为例,我可以在所有主流浏览器甚至 IE8 中重现这一点,即使 script1 抛出错误,也会执行 script2。
    @Marcello 的出色回答仍然有助于深入了解执行堆栈等概念。这两个脚本中的每一个似乎都在单独的执行堆栈中执行。

    最佳答案

    您将它们作为一个脚本运行的第一个假设是不正确的。即使 Script1 抛出错误,Script2 仍会执行。对于一个简单的测试,实现以下文件结构:

    -anyFolder
    --test.html
    --test.js
    --test2.js
    

    test.html 的内容:
    <html>
       <head>
           <script type="text/javascript" src="test.js"></script>
           <script type="text/javascript" src="test2.js"></script>
       </head>
    </html>
    

    test.js 的内容:
    console.log('test before');
    throw('foo');
    console.log('test after');
    

    test2.js 的内容:
    console.log('test 2');
    

    打开 test.html 时的输出(在控制台中):
    test before test.js:1
    Uncaught foo test.js:2
    test 2 
    

    从这个测试中,您可以看到即使 test.js 抛出错误,test2.js 仍然运行。但是,test.js 在遇到错误后停止执行。

    关于如果前面的脚本失败,则执行或不执行 JavaScript 片段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13067354/

    相关文章:

    windows - 如何测试 Windows 错误报告?

    php - 如何消除PHP中的反斜杠

    javascript - 鼠标点击页面上的其他地方(不是在特定的 div 上)

    javascript - 在页面上加载所有 iframe 的全部内容后不显示警报

    javascript - ajax 加载后图像不会立即显示

    c - 如何正确使用套接字的 write() 函数?

    html - : "" 之后的词法错误 <EOF>

    javascript - 尝试使用 React.DOM 设置正文样式

    javascript - 在其中也有链接的表行中使用 onClick

    javascript - 使用 AngularFire 提交多个表单值