[英]Recursive function crashes when it loops many times javascript
我有這個遞歸函數,這給了我一些問題。 它需要像20.000次一樣運行,但是當它循環很多次時,瀏覽器就會崩潰。 任何幫助表示贊賞
var valid = 0, id = 0;
$(document).ready(function() {
$("#fetch").submit(function(event) {
event.preventDefault();
var selected = $(this).find("#site option:selected");
var pieces = selected.text().split("(");
var sitename = pieces[0];
var numbers = pieces[1].slice(0,-1).split("/");
var fetched = numbers[0]; var total = numbers[1];
var members = $(this).find("#members").val();
var time = $(this).find("#wait").val() * 1000;
wait = (time == 0) ? 800 : time;
$("progress").prop("value", 0).prop("max", members * 2).fadeIn();
valid = 0;
function fetchMember(id) {
id++;
$.post("script.php", $("#fetch").serialize() + "&id=" + id )
.done(function(data) {
console.clear();
isUser = ($(data).text().indexOf("Invalid User") == -1);
if (isUser) valid++;
if(valid < members) setTimeout(function(){ fetchMember(id) }, wait);
if (isUser) {
progress();
fetched++;
selected.text(sitename+"("+fetched+"/"+total+")"); //Updating numbers of fetched profiles on the frontend
username = $(data).find(".normal").text() || $(data).find(".member_username").text() || $(data).find("#username_box h1").text();
$(data).find("dt").each(function() {
var text = $(this).text();
if (text == 'Location') country = $(this).next("dd").text();
});
$.post("save.php", { username: username } )
.done(function(data) {
$("#test").append(id+" "+data + "<br />");
progress();
});
}
});
}
fetchMember(id);
});
});
該功能需要重復20.000次,默認間隔為800ms,甚至更多,例如10分鍾
此函數不是遞歸的,它只是使用setTimeout在將來的某個時刻再次調用自身,這與真正的遞歸不同。
但是,您正在使用傳遞給函數的全局變量,這將導致您在將問題作為副本傳遞時進行范圍界定。 通過將id傳遞給定時呼叫,您正在創建一個閉包,該閉包的次數為20,000次,可能會導致您遇到一些問題。
嘗試如果這是內存問題,但查看代碼我看不到。
var valid = 0, id = 0;
$(document).ready(function() {
$("#fetch").submit(function(event) {
event.preventDefault();
var selected = $(this).find("#site option:selected");
var pieces = selected.text().split("(");
var sitename = pieces[0];
var numbers = pieces[1].slice(0,-1).split("/");
var fetched = numbers[0]; var total = numbers[1];
var members = $(this).find("#members").val();
var time = $(this).find("#wait").val() * 1000;
wait = (time == 0) ? 800 : time;
$("progress").prop("value", 0).prop("max", members * 2).fadeIn();
valid = 0;
fetchMember(id,selected,pieces,sitename,numbers,fetched,members,time,wait);
});
});
function fetchMember(id,selected,pieces,sitename,numbers,fetched,members,time,wait) {
id++;
$.post("script.php", $("#fetch").serialize() + "&id=" + id )
.done(function(data) {
console.clear();
isUser = ($(data).text().indexOf("Invalid User") == -1);
if (isUser) valid++;
if (isUser) {
progress();
fetched++;
selected.text(sitename+"("+fetched+"/"+total+")"); //Updating numbers of fetched profiles on the frontend
username = $(data).find(".normal").text() || $(data).find(".member_username").text() || $(data).find("#username_box h1").text();
$(data).find("dt").each(function() {
var text = $(this).text();
if (text == 'Location') country = $(this).next("dd").text();
});
$.post("save.php", { username: username } )
.done(function(data) {
$("#test").append(id+" "+data + "<br />");
progress();
if(valid < members) setTimeout(function(){ fetchMember(id,selected,pieces,sitename,numbers,fetched,members,time,wait) }, wait);
});
}
});
}
內存泄漏參考http://javascript.crockford.com/memory/leak.html ... jQuery不會泄漏。
[Exhibit 4 - Leak test with a closure]
<html>
<head>
<script type="text/javascript">
function LeakMemory(){
var parentDiv = document.createElement("div");
parentDiv.onclick=function(){
foo();
};
parentDiv.bigString =
new Array(1000).join(new Array(2000).join("XXXXX"));
}
</script>
</head>
<body>
<input type="button"
value="Memory Leaking Insert" onclick="LeakMemory()" />
</body>
</html>
這是您要壓入堆棧的20,000個函數調用。 那是非常占用內存的。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.