Unexplicable changes if I add an "alert"
please help on this issue: Within a loop, I first call a function, which will change the content of a DIV, and then try to display the new content. The code is (in brief):
while (...){
fetch(website_url);
// alert("useless");
x=document.getElementById("prova").textContent;
alert(x);
}
"Fetch" is a function that uses jQuery to open the specified URL and paste the content in the DIV "prova". See the commented "alert"? If I keep it commented, the "fetch" works perfectly (I see the fetched code in the browser window) but the second alert doesn't! It shows the PREVIOUS DIV content (i.e., the first time it is blank, on the second iteration will show the content of the first iteration, etc ...). However, if I uncomment the first alert, the second alert works fine. It clearly looks like a synchronization issue, but I've tried in a lot of ways (i.e. with timeouts, ifs, ..) and I haven't been able to solve it. Any suggestion?
Here is the fetch function (actually it is not mine ... I'm just learning how to use it)
function fetch(url){
container = $('#prova');
doAjax(url);
function doAjax(url){
$.getJSON("http://query.yahooapis.com/v1/public /yql?"+"q=select%20*%20from%20html%20where%20开发者_C百科url%3D%22"+encodeURIComponent(url)+"%22&format=xml'&callback=?",
function(data){
if(data.results[0]){
var data = filterData(data.results[0]);
container.html(data);
} else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg);
}
}
}
You seem to be completely ignoring what AJAX is here: you're making an asynchronous page request to Yahoo, which means you set the browser making the request, then continue processing your script while you wait. That's the entire purpose.
The response text is not available immediately after you set the call, but when you add an alert
you're adding a human-dependent delay that just happens to be long enough for the asynchronous request to come back, in your case.
You could make the AJAX request synchronous ("AJAX" as "Asynchronous Javascript And XML" is a misnomer, and is better called XmlHttpRequest):
var url = "http://query.yahooapis.com/v1/public /yql?"+"q=select%20*%20from%20html%20where%20url%3D%22"+encodeURIComponent(url)+"%22&format=xml'&callback=?";
// Your asynchronous call:
$.getJSON(url, function(data) { ... });
// A synchronous alternative:
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
data: {},
async: false,
success: function(data) { ... },
});
Now the request will complete (or fail) before your code continues.
Or, if you want to keep the asynchronous request, you can move the code that you want to happen after it completes into the callback function:
while (...) {
function myFunction() {
var x = document.getElementById("prova").textContent;
alert(x);
}
fetch_and_handle(website_url, myFunction);
}
function fetch_and_handle(url, handler) {
var container = $('#prova');
var url = "http://query.yahooapis.com/v1/public /yql?"+"q=select%20*%20from%20html%20where%20url%3D%22"+encodeURIComponent(url)+"%22&format=xml'&callback=?";
$.getJSON(url, function(data) {
if (data.results[0]) {
var data = filterData(data.results[0]);
container.html(data);
if (handler != undefined) {
handler();
}
}
else {
var errormsg = '<p>Error: could not load the page.</p>';
container.html(errormsg);
}
});
}
I've also added var
in a few places: when you're creating a local variable, use var
. And I fixed some indentation.
This code depends on timing. The first alert creates a delay during which the fetch completes.
What you want to do is use jQuery ajax with a callback, e.g.
$.get('ajax/test.html', function(data) {
$('.result').html(data);
alert('Load was performed.');
});
see http://api.jquery.com/jQuery.get/
sound like you havn't understood what asynchronous communication is or how it works. in your code, when this line gets executed:
x=document.getElementById("prova").textContent;
the ajax-call (fetch()
) is still running. by putting the "useless" alert in place, the ajax-call has the time to get completed, as the following line will wait for you to click "ok" before it gets executed.
to solve this, you have two possibilitys:
- change your request to be synchronous (but thats a bad idea almost every time)
- use the success-callback of your ajax-request to execute code that should wait for the request to finish
EDIT: you havn't posted your code for fetch()
, so it's a matter of conjecture that you're using some of jquerys's ajax-function in there... posting the complete code would have been nice.
精彩评论