for循环中的Ajax将变量i值增加到总长度

时间:2013-05-13 11:48:18

标签: jquery ajax file upload

我正在开发一个带进度条的ajax上传,如果文件输入不是多个没有问题,但我想开发一个多个ajax上传,为此我创建了一个“for”循环,直到有多少个文件用户已选择。

当函数进入此处时,indice的值是len变量的值,为什么会发生这种情况?

 myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false);

完整的代码:

<script type="text/javascript">
    $(document).ready(function(e){
        $('#uploader').submit(function(){
            var inpf = document.getElementById('files');
            var len = inpf.files.length;
            //console.log(inpf, len);return false;
            for(var i=0; i<len; i++){
                var indice = i;
                $('div').append('<progress class="prog'+i+'" value="0"></progress><br />');
                var formData = new FormData();
                formData.append('image', inpf.files[i]);
                $.ajax({
                    url: 'upload1.php',  //server script to process data
                    type: 'POST',
                    xhr: function() {  // custom xhr
                        var myXhr = $.ajaxSettings.xhr();
                        if(myXhr.upload){ // check if upload property exists
                            myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(indice)) }, false); // for handling the progress of the upload
                        }
                        return myXhr;
                    },
                    //Ajax events
                    //beforeSend: beforeSendHandler,
                    success: function(data){
                        completeHandler(data, '.prog'+i);
                    },
                    //error: errorHandler,
                    // Form data
                    data: formData,
                    //Options to tell JQuery not to process data or worry about content-type
                    cache: false,
                    contentType: false,
                    processData: false,
                });
            }
            return false;
        });
    });

    function progressHandlingFunction(e, klass){
        if(e.lengthComputable){
            $(klass).attr({value:e.loaded, max:e.total});
        }
    }

    function completeHandler(data, klass){
        $(klass).attr({value:0});
    }
</script>

这里有jsFiddle示例: http://jsfiddle.net/Pgq9s/

2 个答案:

答案 0 :(得分:2)

循环启动了很多ajax请求。启动所有请求后,i达到最大值。

然后,ajax请求的结果开始出现,并且执行了success回调函数。

,当所有回调都被执行时,i仍然是最大值。

答案 1 :(得分:2)

变量i的范围是整个函数,而不是for循环的特定迭代。在执行success回调函数时,for循环将完整执行,i将在最后一次迭代后等于其值(i == len )。

使用立即调用的函数表达式来创建闭包,为该迭代保留i的值:

for(var i=0; i<len; i++){
    var indice = i;
    $('div').append('<progress class="prog'+i+'" value="0"></progress><br />');
    var formData = new FormData();
    formData.append('image', inpf.files[i]);
    (function(index) {
    $.ajax({
        url: 'upload1.php',  //server script to process data
        type: 'POST',
        xhr: function() {  // custom xhr
            var myXhr = $.ajaxSettings.xhr();
            if(myXhr.upload){ // check if upload property exists
                myXhr.upload.addEventListener('progress', function(e) { progressHandlingFunction(e, '.prog'+(index)) }, false); // for handling the progress of the upload
            }
            return myXhr;
        },
        //Ajax events
        //beforeSend: beforeSendHandler,
        success: function(data){
            completeHandler(data, '.prog'+index);
        },
        //error: errorHandler,
        // Form data
        data: formData,
        //Options to tell JQuery not to process data or worry about content-type
        cache: false,
        contentType: false,
        processData: false,
    });
    })(i);
}