2017-06-22 226 views
0

我正在研究一个广泛使用AJAX和jQuery事件的应用程序,并且遇到了我无法解释的奇怪行为。违规的篡改版本的片段:jQuery.Deferred异常 - 对事件处理程序的未请求调用

$(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 exception: result is not defined ReferenceError: result is not defined

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

进一步混淆我的努力弄清楚是怎么回事是完全改变了事件名称"refresh.begin""refresh.done""refresh.fail"解决问题的事实。究竟是什么造成了错误的第一个电话?

回答

0

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

  • 事件名称中的时间段(例如"app.refresh.done")使得jQuery将名称空间应用于事件。
  • 事件名称第一位,后面跟着命名空间,它们是而非分层,其工作方式与CSS类相似。 "app.refresh.done"表示“刷新”和“完成”命名空间中的“应用程序”事件。
  • 触发事件时,会触发所有匹配事件名称并存在于指定名称空间中的事件。触发"app.refresh"将触发“刷新”命名空间中的所有“应用程序”事件。

在上面的代码"app.refresh""app.refresh.done",并"app.refresh.fail""app.refresh"触发被称为 - 他们都是“应用程序”事件中的“刷新”的命名空间。

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