Javascript变量未更新 - 可能超出范围

时间:2011-08-25 23:45:50

标签: javascript jquery ajax scope

  

可能重复:
  AJAX- response data not saved to global scope?

我基本上有一个循环,使用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定义为全局变量?

感谢您的帮助。

3 个答案:

答案 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调用
$.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);
        }
    });
}