2013-03-17 3 views
0

A partir de this question, j'ai compris que je pouvais utiliser une boucle forEach ou une auto-invoquée pour effectuer des opérations d'E/S asynchrones. Je ne sais pas pourquoi cela ne fonctionne pas pour moi, mais la partie en boucle fonctionne correctement sans qu'aucune fonction asynchrone ne soit appelée.Fonction auto-invoquée récursive et opérations asynchrones

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

Ma sortie de la console est un peu étrange:

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

Deux questions ici:

  1. Comment puis-je résoudre ce problème pour qu'il passe de fileA à fileH?
  2. Après l'analyse des fichiers, que je mets le code pour travailler avec la variable json après la fonction appelée auto ou dans la boucle else dans la fonction then de la promesse retournée par readFileAsync()?
+0

Vous incrémentez la valeur si 'i' provient de la fonction asynchrone, vous devez probablement le déplacer vers la fonction externe et transmettre le nom du fichier. Cela ne garantira pas que les fonctions seront complètes dans l'ordre, vous devrez les synchroniser pour le faire. – RobG

+0

@RobG De toute évidence, vous avez tort. L'incrémentation dans l'appel asynchrone est le point entier de faire ceci. Le code est correct, voir ceci jsFiddle: http://jsfiddle.net/cS7hs/ J'ai remplacé les appels asynchrones par setTimeout. De la sortie, il semble que cette fonction a été appelée deux fois en même temps. L'erreur est ailleurs. – freakish

Répondre

0

Je fini par faire ceci:

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

Je suis juste heureux que les méthodes asynchrones dans la fonction récursive utiliser l'interface Promise, donc je ne dois pas écrire tout un tas de fonctions récursives .

Questions connexes