2012-11-22 57 views
0

我正在使用HTML5多文件上傳器。出於某種目的,我將請求排入一個JavaScript數組,我嘗試了兩種方法,一種是使用for循環通過循環發送所有請求,然後下一種方法就像在上一個請求之後開始下一個請求請求已完成。下面是代碼,xhr.status和xhr.readyState爲0

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; 
} 

但問題是我得到的readyState和狀態爲0的if循環。但是,文件正在上傳到服務器和其他條件也運作良好,如果我只啓用該塊。那麼可能是什麼問題。我很困惑。任何幫助將不勝感激。

回答

1

該問題與您使用onreadystatechange所使用的匿名函數創建的閉包有關。它將獲得i的價值,但不是從創建閉合時起,而是從執行時起。在那個時間點,i總是4,xhrQ[i]不會引用正確的對象。使用this代替

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

    } 
} 

的問題是,要繼續uploadComplete()函數中的指數i。爲此,您可能需要使用立即執行的函數創建另一個內部閉包,該函數將創建當前索引的本地副本。

xhrQ[i].onreadystatechange = (function(_innerI) { 
    var that = this; 
    return function() { 
     if(that.readyState == 4 && that.status == 200) { 
     uploadComplete(that, _innerI); 
     } 
    } 
})(i); 
+0

好回答專家!有用。謝謝 :) – Stranger