【问题标题】:First failing jQuery.ready() breaks the rest第一个失败的 jQuery.ready() 打破了其余的
【发布时间】:2012-01-03 10:50:51
【问题描述】:

我们允许用户编写有时会多次调用jQuery.ready(function(){..}) 的代码。似乎第一个引发错误的函数调用阻止了其余函数的执行。

曾讨论过这个here,解决方案是将jQuery.ready() 包装在一个委托中,而不是包装传递给jQuery.ready(..) 的匿名函数参数。

如何覆盖 jQuery.ready(fn) 并将传入的函数参数包装在一个委托中,该委托将其包装在 try/catch 中并传递给 jQuery.ready(delegate)?

这是一个例子:

<head>
  <script>
    // here is some code from third-party developer that sometimes throws an error
    jQuery.ready(function() {
      if ((new Date()).getMonth() == 0) 
        throw Error("It's January!");
    });
  </script>
</head>

<body>
  <script>
    // here is my code which should run regardless of the error in the <head> script
    jQuery.ready(function() {
      alert("I need to run even in January!");
    });
  </script>
</body>

我可以做些什么来让代码运行而不考虑错误?

【问题讨论】:

  • 我们不能将代码包含在 try-catch 块中,因为该代码是由第三方开发人员提供的。这是引用讨论中的海报描述的类似问题。

标签: jquery error-handling


【解决方案1】:

如果您需要自己捕捉错误,请使用自己的try/catch 捕捉它们:

$(document).ready(function() {
   try {
       // put your normal code here
   } catch (e) {
       // put any code you want to execute if there's an exception here
   }
});

这将允许所有后续代码继续进行而不会暂停。有人可能会问为什么会抛出错误?也许你应该做些什么来解决这个问题或更直接地处理这个问题?

如果您愿意,您可以这样做并将所有麻烦的对jQuery.ready() 的调用替换为jQuery.safeReady():

jQuery.fn.safeReady = function(f) {
    jQuery.ready(function() {
        try {
            f();
        } catch(e) {
            // make it so you can see errors in the debugger 
            // so you would know if something was wrong
            if (window.console) {
                console.log(e);
            }
        }
    });
};

【讨论】:

  • 我需要按照你的第二个代码 sn-p 的行做一些事情。但是,它似乎不起作用,因为 jQuery.ready(f) 只是将函数 f 排队以供以后执行(当 DOM 准备好时)。当发生这种情况时,执行 f 会引发错误,从而阻止执行其他排队的函数。这就是为什么在我原来的帖子中我问如何在将函数 f 传递给 jQuery.ready(safeF) 之前将函数 f 的执行包装在 try-catch 委托中,例如 safeF?
  • @alecswan - 很好,我已经修改了答案中的第二个示例以解决该问题。
  • 你没有向下传递 f 参数,但我认为这在这种情况下应该可以工作,因为函数 f 在传递给 jQuery.ready(f) 时永远不能有任何参数,对吧?
  • 假设我在 中有一些由第三方提供的 JavaScript 代码,而我的
  • @alecswan - 您不能将参数传递给 .ready() 回调函数,因此这不是问题。
【解决方案2】:

你可以这样覆盖它:

jQuery.fn.ready = function(param){
    // do whatever you wish
};

但是你不应该这样做。出于某种原因,请参阅this jsfiddle。

我的 jsfiddle 中的示例显示,上述解决方案还会覆盖常用的 jQuery 功能,并且会严重破坏您的代码。

只需重写您的代码 - 将 .ready() 更改为 .delegate() 或将编写不佳的代码包含在 try {...} catch(...) {...} 语句中。

【讨论】:

  • 但是如果你的ready 处理程序是可靠的,它不应该引起这些问题......我不明白你的小提琴证明了什么。 jsfiddle.net/26KUU
【解决方案3】:

值得知道的是,在 JQuery 3.0 中这种行为已经改变,JQuery.ready() 中的一个错误不会阻止其余的触发。

在此处查看官方文档:

https://github.com/jquery/jquery/issues/1823

https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-01-12
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    • 1970-01-01
    • 2022-08-19
    • 2018-11-19
    相关资源
    最近更新 更多