2013-03-17 70 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. 如何解決它,這樣它的fileA去fileH?
  2. 解析完文件後,我是否會將代碼與自調函數後的變量jsonthen函數中的then函數的readFileAsync()返回的函數一起使用?
+0

如果在異步函數中'i'增加了值,則應該將其移動到外部函數並傳入文件名。這不能確保順序完成功能,但你需要使它們同步。 – RobG 2013-03-17 22:23:45

+0

@RobG顯然你錯了。異步調用中的增量是完成此操作的關鍵。代碼是正確的,看到這個jsFiddle:http://jsfiddle.net/cS7hs/我用setTimeout取代了異步調用。從輸出看起來這個函數同時被調用兩次。錯誤在別的地方。 – freakish 2013-03-17 22:26:41

回答

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

我很高興的是,在遞歸函數異步方法使用無極接口,因此我沒有寫一大堆的遞歸函數。