我基本上有一个循环,使用AJAX联系我网站上的脚本,然后使用该脚本的响应更新字符串。这是代码:
// Image code array
var result_url = 'http://localhost/view/';
for(i = 0; i < urls.length; i++) {
// Add URL to queue
$('#url_queue').append('<div class="uploadifyQueueItem"><div class="cancel"><img src="/assets/img/cancel.png" /></div><span class="fileName">' + image_name_from_url(urls[i]) + '</span><div class="uploadifyProgress"><div class="uploadifyProgressBar"></div></div></div>');
// Make a request to the upload script
$.post('/upload', { url: urls[i], username: username }, function(response) {
var response = jQuery.parseJSON(response);
if(response.error) {
alert(response.error);
return;
}
if(response.img_code) {
result_url += response.img_code + '&';
}
});
}
console.log(result_url);
Firebug控制台只在记录字符串时显示http://localhost/view/
。这就像我的上传脚本中的img_code
响应根本没有附加到字符串中。我已尝试在result_url
方法中记录$.post()
的值并且该方法正常,但该值未正确保存,因为它稍后未在我的代码中显示。这是范围问题吗?我是否必须将result_url
定义为全局变量?
感谢您的帮助。
答案 0 :(得分:1)
在AJAX请求完成之前,您正在检查console.log(result_url);
。
AJAX请求(默认情况下)是异步运行的。这意味着您的脚本在继续向服务器发出请求时继续运行。
你的回调函数(作为第3个参数提供给$.post
)是你的AJAX请求完成后执行的函数。
另请注意,请求完成后会调用您的AJAX请求回调函数。您的请求可能无法按照他们开始的顺序完成。你可以通过设置async:false
来阻止所有这一切,但这会阻止你所有的javascript执行。
另一种选择是收集jqXHR
返回的$.post
个对象,然后调用$.when().done()
,这样只有当所有AJAX请求都是console.log(result_url)
时才会发生// Image code array
var result_url = 'http://localhost/view/',
jqHXRs = [];
for(i = 0; i < urls.length; i++) {
// Add URL to queue
$('#url_queue').append('<div class="uploadifyQueueItem"><div class="cancel"><img src="/assets/img/cancel.png" /></div><span class="fileName">' + image_name_from_url(urls[i]) + '</span><div class="uploadifyProgress"><div class="uploadifyProgressBar"></div></div></div>');
// Make a request to the upload script
jqHXRs.push($.post('/upload', { url: urls[i], username: username }, function(response) {
var response = jQuery.parseJSON(response);
if(response.error) {
alert(response.error);
return;
}
if(response.img_code) {
result_url += response.img_code + '&';
}
}));
}
$.when.apply(this, jqHXRs).done(function(){
console.log(result_url);
});
解决的问题:
{{1}}
答案 1 :(得分:0)
这是因为您在解雇Ajax后立即执行console.log
。由于Ajax是异步的,因此不必在遵循ajax代码的代码之前调用success函数。
jQuery的Ajax工具提供了一种通过包含async:false
选项来同步调用ajax的方法。尝试用:
$.ajax({
url:'/upload',
data:{ url: rls[i], username:username },
success:function(response) {
var response = jQuery.parseJSON(response);
if(response.error) {
alert(response.error);
return;
}
if(response.img_code) {
result_url += response.img_code + '&';
}
},
method:"post",
async:false
});
这样,跟随Ajax调用的代码只能在ajax完成后执行。
请记住,虽然这会在Ajax期间锁定您的页面。也许将console.log(result_url);
放在成功回调的末尾会更容易。
答案 2 :(得分:0)
您在循环之后记录了result_url,但$ .post上传请求可能尚未完成。我建议将使用result_url的代码放在延续回调中,并在知道最后一个帖子请求完成后调用它。
e.g。
function continuation_code(result_url) {
// all your code that uses result_url goes here.
}
var result_url = 'http://localhost/view/';
var num_results_returned = 0;
for(i = 0; i < urls.length; i++) {
// Add URL to queue
$('#url_queue').append('<div class="uploadifyQueueItem"><div class="cancel"><img src="/assets/img/cancel.png" /></div><span class="fileName">' + image_name_from_url(urls[i]) + '</span><div class="uploadifyProgress"><div class="uploadifyProgressBar"></div></div></div>');
// Make a request to the upload script
$.post('/upload', { url: urls[i], username: username }, function(response) {
var response = jQuery.parseJSON(response);
if(response.error) {
alert(response.error);
return;
}
if(response.img_code) {
result_url += response.img_code + '&';
}
num_results_returned += 1;
if (num_results_returned == urls.length) {
continuation_code(result_url);
}
});
}