0

我正在使用 HTML5 多文件上传器。出于某种目的,我将请求排队到 JavaScript 数组中,我在这里尝试两种方法,一种是使用 for 循环通过循环发送所有请求,下一种方法就像在前一个请求之后开始下一个请求请求完成。这是代码,

    function processUploads(i)
{
    if(typeof(i)=="undefined")
        return;

    if(i==0)
    {
        for(i=0;i<4;i++)
        {
            xhrQ[i].open("POST",FUurl,true);
            xhrQ[i].send(fdQ[i]);
            xhrQ[i].onreadystatechange = function() {
                if (xhrQ[i].readyState == 4 && xhrQ[i].status == 200) {                
                    uploadComplete(xhrQ[i],i);
                }
            }
        }
    }
    else
    {
        xhrQ[i].open("POST",FUurl,true);
        xhrQ[i].send(fdQ[i]);
        xhrQ[i].onreadystatechange = function() {
            if (xhrQ[i].readyState == 4 && xhrQ[i].status == 200) {                
                uploadComplete(xhrQ[i],i);
            }
        }
    }
}

function uploadComplete(xhr,i)
{
    //processUploads(i+1);
    var responseJSON = eval('(' + xhr.responseText + ')');
    var upldrID = responseJSON.data.queueId;

    var fileProgElem = $("#file_content").find("div[file-count="+upldrID+"]");
    fileProgElem.attr("upload","finished");
    fileProgElem.find("input[id=asset_id]").val(responseJSON.data.asset_id);

    if(typeof(responseJSON)=="undefined") {
        return;
    }

    $("#bar"+upldrID).css("width: 100%");
    $("#progress_text"+upldrID).addClass("hide");
    $("#progress_bar"+upldrID).html("Upload Complete!");

    var pagename = $("#pagename").attr('value');

    var cover_art = "<img src='"+responseJSON.data.thumb_location+"' alt='"+$.trim($("#file_name"+upldrID).html())+"' />";
    $("#cover_art"+upldrID).html(cover_art);

    //Hide the cross icon and enable the save 
    var action_divs = '<div id="done'+upldrID+'" class="hide enable">'
            +'<a id="delete_file_'+upldrID+'" onclick="saveWorkspaceFileDetails(\''+responseJSON.data.project_id+'\',\''+responseJSON.data.asset_id+'\',\''+upldrID+'\',\''+responseJSON.data.file_name+'\',\''+responseJSON.data.size+'\',\'delete\',\''+pagename+'\')">'
            +'<i class="tl-icon-20-close-gray"></i>'
            +'</a>'
            +'</div>';

    $("#cancel_upload"+upldrID).append(action_divs);

    $("#progress_cancel"+upldrID).addClass("hide").removeClass("show");
    $("#done"+upldrID).addClass("show").removeClass("hide");        

    //To show the post and cancel button
    $("#submitFileUpload").removeClass("hide").addClass("show");

    //Updating the title with the default value of file_name
    var file_title =  $.trim($("#file[file-count='"+upldrID+"']").find("#file_title").val());
    if (file_title == "" && file_title != undefined){
        $("#file[file-count='"+upldrID+"']").find("#file_title").val(responseJSON.data.file_name);
    }

    //For other category we need to enable the dropdown     
    if(responseJSON.data.category_id=='999')
    {
        $("#select_category"+upldrID).removeClass("hide").addClass("show");
    }

            //totSelFiles is a number of selected files that i sets as a global variable
    if(i<(totSelFiles-1))
    {
        processUploads(i+1);
    }
    else
        return;
}

但问题是我在if循环中得到了 readyState 和 status 为 0 。但是文件正在上传到服务器,如果我只启用该块,其他条件也可以正常工作。那么可能是什么问题。我很困惑。任何帮助将不胜感激。

4

1 回答 1

1

问题与您使用用于 onreadystatechange 的匿名函数创建的闭包有关。它将可以访问 的值i,但不是从创建闭包时开始,而是从执行时开始。在那个时间点i总是 4 并且xhrQ[i]不会引用正确的对象。this改为使用

xhrQ[i].onreadystatechange = function() {
   if(this.readyState == 4 && this.status == 200) {

   }
}

问题是您想继续使用iuploadComplete() 函数中的索引。为此,您可能需要使用立即执行的函数创建另一个内部闭包,该函数将创建当前索引的本地副本。

xhrQ[i].onreadystatechange = (function(_innerI) {
   var that = this;
   return function() {
      if(that.readyState == 4 && that.status == 200) {
         uploadComplete(that, _innerI);
      }
   }
})(i);
于 2012-11-22T08:43:20.447 回答