2013-03-17 4 views
0

От this question я понял, что могу использовать цикл forEach или самозапускаемый для выполнения асинхронных операций ввода-вывода. Я не уверен, почему он не работает для меня, но часть цикла работает нормально, без вызова асинхронной функции.Рекурсивная функция самоисключения и асинхронные операции

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. После разбора файлов, я поставил код для работы с переменной json после самостоятельного вызова функции или в else петли в then функции Обещания возвращенного readFileAsync()?
+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(); 
      } 
     }); 
})(); 

Я просто рад, что асинхронные методы в рекурсивной функции использовать интерфейс Promise, так что я не должен писать целую кучу рекурсивных функций ,

Смежные вопросы