我正在编写一个本地运行的小型网络应用,预计会有间歇性的网络访问。考虑到这一点,我正在检查我们的外部依赖(Google Maps)是否无法加载,并在10秒后再次尝试。简要概述:
// Assume the worst
var mapsSuccess = false;
// Only gets invoked by maps success
function initialize(){
// Set the flag to prevent continuous recursion of the previous function
mapsSucess = true;
/* application init */
}
// Invoke immediately
( function mapsCall(){
// Maybe we don't need this...
if( mapsSuccess === true ){
return;
}
$.ajax( {
cache : true,
dataType : 'script',
// `callback` param specifies function to call on successful execution
url : googleMapsUri + '&callback=initialize'
} );
// Run this function again in 10 seconds to see if we succeeded
setTimeout( mapsCall, 10000 )
}() );
问题出在最糟糕的情况,即我们无法成功加载地图数小时。有后备离线内容,但目前内存泄漏最终导致浏览器崩溃。检查Chrome开发工具中的时间表,来源显而易见:
每次重新调用mapsCall
时,都会调用新的DOM节点和新的事件侦听器。我想删除这些并删除任何事件监听器被绑定(具有讽刺意味的是,我的代码没有设置任何事件监听器),所以我在mapsCall
正文中设置了这个:
$( 'script[async][src*="callback=initialize"]' ).off().remove();
这有效地删除了冗余的脚本元素,但由于事件侦听器计数,并没有真正消除内存泄漏。我曾尝试使用$._data( element, 'events' )
嗅探这些神秘事件监听器的绑定位置,但它们不在脚本本身,document
,window
或根元素({{ 1}},html
)所以我不知所措。