2012-03-17 2 views
1

콜백을 사용하는 방법을 천천히 배우고 있으며 문제가 있습니다. 아래 코드는 작동하지 않아야한다고 생각합니다.javascript 콜백이 데이터를 호출 상단으로 푸시하지 않음

내가 '다른'트리 항목을 치거나 끝에 아무 것도 출력하지 않는 경우 재귀 함수로 내림차순으로 전달되지 않는다고 말할 수 있습니다.

내가 만난 문제 중 하나는 for 루프의 콜백입니다. 더 나은 방법이 있는지 확신하지 못했습니다. 콜백을 호출하기 전에 카운터를 사용하여 루프가 끝났는지 확인했습니다.

일부 안내는 정말 감사하겠습니다. 당신은 BLOB 데이터 treeContents를 수집 변수가 새로 생성 parseTree() 모든 호출에 파괴 그래서 재귀 함수의 지역 변수이기 때문에

(function() { 
    'use strict'; 

    var objectsList = []; 

    function makeAJAXCall(hash, cb) { 
     $.ajaxSetup({ 
      accept: 'application/vnd.github.raw', 
      dataType: 'jsonp' 
     }); 

     $.ajax({ 
      url: hash, 
      success: function (json) { 

       if (cb) { 
        cb(json); 
       } 
      }, 
      error: function (error) { 
       console.error(error); 
       throw error; 
      } 
     }); 
    } 

    function parseBlob(hash, cb) { 
     makeAJAXCall(hash, function (returnedJSON) { // no loop as only one entry 
      if (cb) { 
       cb(returnedJSON.data); 
      } 
     }); 
    } 

    function complete(cb, loopLength, treeContents) { 
     concole.info(loopLength); 
     if (cb && loopLength === 0) { 
      objectsList.push(treeContents); 
      cb(); 
     } 
    } 

    function parseTree(hash, treeName, cb) { 
     var treeContents = {'tree': treeName, 'blobs': []}, loopLength, i, entry; 
     var tree = 'https://api.github.com/repos/myusername/SVG-Shapes/git/trees/' + hash; 
     makeAJAXCall(tree, function (returnedJSON) { 
      loopLength = returnedJSON.data.tree.length; 
      for (i = 0; i < returnedJSON.data.tree.length; i += 1) { 
       entry = returnedJSON.data.tree[i]; 
       if (entry.type === 'blob') { 
        if (entry.path.slice(-4) === '.svg') {  // we only want the svg images not the ignore file and README etc 
         parseBlob(entry.url, function (json) { 
          treeContents.blobs.push(json.content); 
          loopLength -= 1; 
          complete(hash, loopLength, cb); 
         }); 
        } 
       } else if (entry.type === 'tree') { 
        parseTree(entry.sha, entry.path, function() {console.info(objectsList);}); 
       } 
      } 
     }); 
    } 

    $(document).ready(function() { 
     parseTree('master', 'master', function() {  // master to start at the top and work our way down 
      console.info(objectsList); 
     }); 
    }); 
}()); 

답변

3

당신의 재귀가 제대로 작동하지 않습니다. 데이터를 누적하지 않습니다. 이 변수를 parseTree() 함수의 범위 밖에서 만들어야 만이 변수의 단일 인스턴스가 한 호출에서 다음 호출로 살아갈 수 있고 올바르게 그 안에 데이터를 누적 할 수 있습니다.

  1. 당신은 당신이 함수의 재귀 부분은 공통을 공유하는 지역 함수가 될 만들 수있는 parseTree() 기능
  2. treeContents의 현재 상태를 전달할 수 있습니다

    이 해결 방법에는 여러 가지가 있습니다 treeContents 변수.

  3. treeContents 변수를 전역 변수로 만들 수 있습니다.

두 번째는 내 선택이 여기에이 같은 것입니다 :

function parseTree(topHash, topTreeName, topCb) { 
    var treeContents = {'tree': toptreeName, 'blobs': []}; 

    function parse(hash, treeName, cb) { 
     var loopLength, i, entry; 
     var tree = 'https://api.github.com/repos/myusername/SVG-Shapes/git/trees/' + hash; 
     makeAJAXCall(tree, function (returnedJSON) { 
      loopLength = returnedJSON.data.tree.length; 
      for (i = 0; i < returnedJSON.data.tree.length; i += 1) { 
       entry = returnedJSON.data.tree[i]; 
       if (entry.type === 'blob') { 
        if (entry.path.slice(-4) === '.svg') {  // we only want the svg images not the ignore file and README etc 
         parseBlob(entry.url, function (json) { 
          treeContents.blobs.push(json.content); 
          loopLength -= 1; 
          complete(hash, loopLength, cb); 
         }); 
        } 
       } else if (entry.type === 'tree') { 
        parse(entry.sha, entry.path, function() {console.info(objectsList);}); 
       } 
      } 
     }); 
    } 

    parse(topHash, topTreeName, topCb); 
} 

는 AJAX 호출이 비동기 가정하면, 당신은 여전히 ​​당신은 모든 구문 분석을 완료하면 알 수있는 방법을 찾아야하고 그렇지 않으면 데이터가 다른 함수에서 사용 가능하지 않기 때문에 treeContents 데이터를 전달하는 일부 함수를 호출하십시오. ajax 호출의 비동기 특성 때문에 parseTree에서 단순히 반환 할 수 없습니다.

관련 문제