2017-06-22 231 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來說明。