2017-03-01 75 views
0

我正在與https://github.com/sameer-shelavale/blitz-gmap-editor;文件test5.html有讓您留下一個標記,當你點擊它,你就會得到一個表格來編輯它的屬性:在第三方庫中使用異步函數調試JavaScript?

blitz-gmaps

我已通過添加一些額外的按鈕,與添加標記開始預先填充的數據。然後,我點擊它們以便顯示錶格,我在表格中編輯任何內容,然後按取消。大約一半在此之後第二個一秒,我得到了瀏覽器控制檯:

TypeError: a.url.substr is not a function util.js:202:114 

我很想擺脫這種錯誤的(請注意,在原來test5.html不會發生)。

問題是 - 首先我不知道這個功能是什麼或做什麼;我發現Do we have a Uncompressed javascript Library for Google Maps API V3

沒有未壓縮的庫。所有API方法都根據發佈的文檔進行訪問,因此不需要是未壓縮的版本。

是的,沒錯 - 絕對沒有必要,當然!當然,谷歌並不在乎他們的財產 - 只是沒有人會需要知道發生了什麼事情,因爲它不可能進入一個不好的問題:)

無論如何,堆棧跟蹤火狐吐出是:

rz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:202:114 
qz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:201:427 
_.yz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:204:224 
dz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:200:287 
cz.prototype.load http://maps.googleapis.com/maps-api-v3/api/js/26/17/util.js:199:133 
SS http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:5:217 
WS http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:7:482 
XS http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:7:116 
VS.prototype.Y http://maps.googleapis.com/maps-api-v3/api/js/26/17/marker.js:35:646 
_.zf.prototype.L/a.F< http://maps.googleapis.com/maps/api/js:112:4221 

...,鉻輸出這樣的:

util.js:202 Uncaught TypeError: a.url.substr is not a function 
rz.load @ util.js:202 
cz.load @ util.js:199 
oz @ util.js:6 
lz @ util.js:6 
kz.load @ util.js:201 
qz.load @ util.js:201 
_.yz.load @ util.js:204 
dz.load @ util.js:200 
cz.load @ util.js:199 
SS @ marker.js:5 
WS @ marker.js:7 
XS @ marker.js:7 
VS.Y @ marker.js:35 
(anonymous function) @ js?v=3.26&libraries=drawing,geometry:112 

所以,顯然rz.prototype.load發生錯誤,並正在由_.zf.prototype.L/a.F<是啓動;從Firefox的信息(...地圖/ API/JS:112:4221),我這個提取爲_.zf.prototype...

... 
_.zf.prototype.L=function(){ 
    var a=this; 
    a.F||(
     a.F=window.setTimeout(
      function(){ 
      a.F=void 0; // <=== column:4221 here at ; 
      a.Y() 
      } 
      ,a.ql) 
     ) 
}; 
... 

這對於rz.prototype(其中包含util.js:202:114):

... 
rz.prototype.load=function(a,b){ 
    var c=this.la; 
    this.b&&"data:"!=a.url.substr(0,5)||(a=new _.ez(a.url)); // column 114 is right before a.url.substr.. 
    return c.load(a,function(d){ 
    !d&&_.m(a.crossOrigin)?c.load(new _.ez(a.url),b):b(d) 
    }) 
}; 
... 

所以,呼叫者_.zf.prototype.L函數會執行setTimeout,最終會調用rz.prototype,這就解釋了爲什麼只有在按「取消」後一段時間過期後纔會顯示此錯誤。

但我的問題是 - 在代碼的其餘部分,它可能會稱這_.zf.prototype.L函數是什麼?我如何找到?如果_.zf.prototype.L本身是通過setTimeout調用的,它是否會「記住」始發的調用者/調用堆棧,並且可以檢索它以進行調試?或者,是否可以設置一個斷點,該斷點只要名稱爲_.zf.prototype.L的函數即將被調用就會中斷?

我試圖調查How to view JavaScript function calls as they occur(它沒有關於如何做函數調用跟蹤的信息);然後找到https://javascriptweblog.wordpress.com/2010/06/01/a-tracer-utility-in-2kb/ - 使用此庫,我可以這樣做:

tracer.traceAll(BlitzMap,true); 
tracer.traceAll(BlitzMap.getMapObj(),true); 

....但是它跟蹤了對象函數OK,地圖obj有點奇怪(在頁面加載時控制檯中有3000+ tracing traceOff消息),但它似乎也跟蹤了一些部分 - 但是,當我執行測試用例時,按下「取消」所有我得到的是我的代碼跟蹤(不會崩潰),然後第二個過去了,我得到上面的錯誤/堆棧跟蹤沒有任何其他跟蹤。

那麼,如何調試這樣的問題呢?

回答

1

好吧,我設法找到了解決這個問題的地方 - 即使近距離投票聲稱問題「太寬泛」。

首先,如果從API的 「前置」 的javascript:

<script src="http://maps.googleapis.com/maps/api/js?v=3.26&libraries=drawing,geometry" type="text/javascript"></script> 

...然後將其下載到文件:

wget "http://maps.googleapis.com/maps/api/js?v=3.26&libraries=drawing,geometry" -O gmapsapi.js 

...並使用此文件在你的HTML而不是在線的:

<script src="gmapsapi.js" type="text/javascript"></script> 

然後打開你的HTML文件在Firefox中,讓它運行,然後在Firefox中執行:File/Save Pa ge as /網頁,完成。

這將在保存的頁面文件夾中本地下載其他腳本,如util.js等。

現在,打開HTML文件的保存(作爲網頁,完整)版本 - 它也應該將在線鏈接替換爲下載的本地腳本。

然後,打開gmapsapi.js從保存的文件夾,並引入換行到_.zf.prototype.L功能:

_.zf.prototype.L=function(){ 
    var a=this; 
    a.F||(a.F=window.setTimeout(function(){a.F=void 0;a.Y()},a.ql)) 
}; 

...到以後能夠設置一個斷點上線。

現在,在Firefox中打開保存的HTML文件,打開Firebug,在腳本標籤中找到gmapsapi.js,並在var a=this;行上設置斷點。

現在運行的東西 - 在我的情況下,做所有事情,包括按下取消 - 和JS引擎將打破;那麼您可以在Firebug的控制檯做console.trace(),並獲得這種痕跡的(後發生錯誤):

_.zf.prototype.L()       gmapsapi.js (line 114) 
VS.prototype.changed(a="modelIcon")   marker.js (line 35) 
Bb(a=Object { type="object"}, b="modelIcon") gmapsapi.js (line 37) 
Bb(a=Object { type="object"}, b="icon")  gmapsapi.js (line 37) 
_.k.set(a="icon", b=Object { type="object"}) gmapsapi.js (line 96) 
_.vc/<(c=Object { type="object"})    gmapsapi.js (line 47) 
_.k.setValues()        gmapsapi.js (line 97) 
a = Object { type="object"} 
BlitzMap</this.updateOverlay()    blitz.js (line 545) 
BlitzMap</this.closeInfoWindow()    blitz.js (line 514) 
onclick()input[3] onclick (line 1) 
event = Object { type="object"} 

...果然 - 這指出了其中的錯誤是:即,我砍死blitz.js,最後寫了一個空字符串""作爲標記的圖標,最終導致了錯誤。

這個堆棧跟蹤揭示了一件事 - 那就是爲什麼這個錯誤只發生在我第一次按取消,而不是後來的時間;好的,答案是,錯誤的代碼只在VS.prototype.changed(a="modelIcon")時運行,所以第二次,空字符串的設置不再是「變化」了,所以沒有錯誤。