I have been working on a pretty big javascript function, and when I finally thought it was done, it stopped working completely.
Here it is:
function getLinksFrom(title) {
var returnArray = [],
plcontinue = '',
url = 'http://en.wikipedia.org/w/api.php?action=query&prop=links&titles=' + title + '&format=json&pllimit=500&plnamespace=0&callback=?';
while (returnArray.length === 0 || plcontinue !== '') {
if (plcontinue !== '') {
url = 'http://en.wikipedia.org/w/api.php?action=query&prop=links&titles=' + title + '&format=json&pllimit=500&plnamespace=0&plcontinue=' + plcontinue + '&callback=?';
}
$.ajax({url: url,
dataType: 'json',
success: function(data) {
console.log(data);
for (key in data['query']['pages']) {
links = data['query']['pages'][key]['links'];
}
for (var i = 0; i < links.length; i += 1) {
returnArray.push(links[i]['title']);
}
if (data.hasOwnProperty('query-continue')) {
plcontinue = data['query-continue']['links']['plcontinue'];
} else {
plcontinue = '';
}
}
});
}
return returnArray;
}
from what I can tell, it must be getting stuck in the while loop, as the page just freezes up. But with each loop, returnArray grows, and I’m testing it with something that won’t set plcontinue to anything.
Any idea what is going wrong? Possibly something with asynchronous loading, I’m new at that.
EDIT: So I’ve figured out via helpful comments that it’s looping again and again making more and more requests without waiting for the ajax to finish before starting again. How can I stop it from doing that?
The key is that AJAX is asynchronous. That means that when JS needs to perform request, it sends it and goes on, continuing to execute the rest of the code. When request is done, callback is fired.
So in your code it would works like that:
Eventually, maybe, one of dozen of request will end, modify
returnArrayandplcontinue, but this could take long time because what you have in your function body is, basically, infinite (almost) loop, which takes most of CPU resources.The solution is to replace iteration with recursion: instead of iterating in infinite loop untill success, you can recurse until success. Delete while loop from
getLinksFromand addgetLinksFrom()to the ajax request callback.Another approack is to do that request synchronous. There is a special flag for it.