2013-03-17 6 views
0

this question에서 forEach 루프 또는 자체 호출을 사용하여 비동기 I/O 작업을 수행 할 수 있다고 결론을 냈습니다. 나는 왜 그것이 나를 위해 작동하지 않는지 모르겠지만 루프의 일부는 제대로 작동하지 않고 호출되는 비동기 함수없이 제대로 작동합니다.재귀 자체 호출 함수 및 비동기 작업

var fileNames = ["fileA", "fileB", "fileC", "fileD", "fileE", "fileF", "fileG", "fileH"]; 
var json; 

(function parseFiles(i) { 

    console.log(i + " " + fileNames[i]); 

    var uri = new Windows.Foundation.Uri('ms-appx:///data/' + fileNames[i] + '.json'); 

    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).then(function (file) { 
     Windows.Storage.FileIO.readTextAsync(file).then(function (contents) { 
      json[fileNames[i]] = JSON.parse(contents); 

      if (i < fileNames.length) { 
       parseFiles(i+1); 
      } else {} 
     }); 
    }); 

})(0); 

내 콘솔 출력의 종류 이상하다 : 여기

0 fileA 
1 fileB 
0 fileA 
2 fileC 
1 fileB 
3 fileD 
2 fileC 
3 fileD 

두 질문 :

  1. 이 fileH에 FILEA에서 들어가도록 나는 그것을 해결 방법은?
  2. 파일을 구문 분석 한 후 자체 호출 된 함수 또는 readFileAsync()에 의해 반환 된 약속의 then 함수의 else 루프에서 변수 json과 함께 작동하도록 코드를 넣으시겠습니까?
+0

비동기 함수에서'i' 값을 늘리면 외부 함수로 이동하고 파일 이름을 전달해야합니다. 함수가 순차적으로 완료되는 것을 보장하지는 않지만, 그렇게하기 위해서는 함수를 동기화시켜야합니다. – RobG

+0

@RobG 분명히 틀렸어. 비동기 호출의 증가가이를 수행하는 전체적인 시점입니다. 이 코드는 정확합니다. jsFiddle : http://jsfiddle.net/cS7hs/ 비동기 호출을 setTimeout으로 대체했습니다. 출력에서이 함수가 동시에 두 번 호출 된 것처럼 보입니다. 오류는 다른 곳에서 발생합니다. – freakish

답변

0

나는이 일을 결국 :

var fileNames = ["fileA", "fileB", "fileC", "fileD", "fileE", "fileF", "fileG", "fileH"]; 
var json; 

(function parseFiles() { 

    var name = fileNames.pop(); 

    Windows.Storage.StorageFile.getFileFromApplicationUriAsync(new Windows.Foundation.Uri('ms-appx:///data/' + name + '.json')) 
     .then(function (file) { 
      return Windows.Storage.FileIO.readTextAsync(file); 
     }, function error(e){ 
      console.dir(e); 
     }) 
     .then(function (contents) { 
      json[name] = JSON.parse(contents); 
     }) 
     .then(function() { 
      console.log("Name: "+name+" Remaining array length:"+fileNames.length); 

      if (fileNames.length === 0) { 
       console.log('all done'); 
       // do whatever else here 
      } else { 
       parseFiles(); 
      } 
     }); 
})(); 

나는 재귀 함수의 전체 무리를 작성하지 않아도 재귀 함수의 비동기 방법이 약속 인터페이스를 사용하는 것이 다행이야 .