2012-11-22 5 views
0

저는 HTML5 다중 파일 업 로더를 사용하고 있습니다. 몇 가지 목적을 위해 요청을 자바 스크립트 배열에 넣기 위해 여기에 두 가지 접근법을 시도합니다. 하나는 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; 
} 

은 그러나 문제는 내가 if 루프에서 0으로 readyState의 상태를 얻고있다. 그러나 파일이 서버에 업로드되고 else 조건 만 잘 작동하면 잘 작동합니다. 그래서 문제가 될 수 있습니다. 나는 크게 혼란 스럽다. 어떤 도움이라도 대단히 감사 할 것입니다.

답변

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

관련 문제