jQuery.Deferred异常 - 对事件处理程序

时间:2017-06-22 18:02:48

标签: jquery ajax events

我正在开发一个广泛使用AJAX和jQuery事件的应用程序,并且遇到了我无法解释的奇怪行为。违规代码段的篡改版本:

$(document).on("app.refresh", function(jqEvent) {
    //app.server.get returns an AJAX promise
    app.server.get("url/goes/here").
        done(function(result) { $(document).trigger("app.refresh.done", [result]); }).
        fail(function() { $(document).trigger("app.refresh.fail"); });
}

$(document).on("app.refresh.done", function(jqEvent, result) {
    if (result.success)
        cache(result.data);
}

$(function() {
    $(document).trigger("app.refresh");
});

"app.refresh.done"的处理程序执行两次。第二次执行堆栈显示来自$(document).trigger("app.refresh");的调用,使用AJAX调用返回的数据来填充result,并且完成且没有错误。但是第一次执行时:

  • 没有向服务器发出请求(通过AJAX访问的端点上的断点不会被命中)
  • 由于未访问服务器,resultundefined,导致行if (result.success)出错:
      

    jQuery.Deferred异常:结果未定义ReferenceError:结果未定义

  • 执行时的堆栈显示调用不是来自触发器。它起源于jQuery中一个名为mightThrow的函数,该函数包含在一个名为process的函数中。

进一步混淆我的努力以弄清楚发生了什么事实是将事件名称更改为"refresh.begin""refresh.done""refresh.fail"完全解决了这个问题。什么导致错误的第一次通话?

1 个答案:

答案 0 :(得分:0)

在阅读相关文档后,很明显这是由.on().trigger()处理event namespacing的方式引起的问题。总结:

  • 事件名称中的句点(例如"app.refresh.done"使jQuery将名称空间应用于事件。
  • 首先是事件名称,然后是命名空间,不是分层,与CSS类的工作方式类似。 "app.refresh.done"代表" app"在"刷新"中的事件和"完成"命名空间。
  • 触发事件时,将触发与事件名称匹配且存在于指定命名空间中的所有事件。触发"app.refresh"将触发所有" app" "刷新"中的事件命名空间。

在上面的代码"app.refresh"中,"app.refresh.done""app.refresh.fail""app.refresh"被触发时被调用 - 它们都是" app" "刷新"中的事件命名空间。

我在JSFiddle上创建了an example来说明。