2013-11-22 4 views
4

Я создаю собственное настольное приложение в javascript, используя CEF, и у меня есть API для доступа к файловой системе из CEF. У меня есть senario, , в котором мне нужно получить имена всех файлов (могут быть деревья каталогов) в пределах определенного каталога. Мне нужно получить массив результатов, я использую обещания jquery. Я не понимаю: когда я разрешу обещание получить окончательный массив результатов?Асинхронный вызов внутри рекурсивной функции

/*read all directories under this and get path*/ 
    var result = []; 
    function _processEntries(dirPath) { 
     var dirEntry = new NativeFileSystem.DirectoryEntry(dirPath), deferred = new $.Deferred(); 

     /*async call*/ 
     dirEntry.createReader().readEntries(
      function (entries) { 
       for (var i = 0; i < entries.length; i++) { 
        if (entries[i].isDirectory) { 
         _processEntries(entries[i].fullPath).done(function() { 
          deferred.resolve(result); 
         }); 
        } else { 
         result.push(entries[i].fullPath); 
        } 
       } 
      }, 
      function (error) { 
       console.log("Failed while reading dir:", error); 
      } 
     ); 
     return deferred.promise(); 
    } 

// Вызов функции

_processEntries("C:/Users/abc").done(function(result){ 
    console.log("FILES ARRAY:",result); 
}); 

Пожалуйста, предложите любую другую технику, если я делаю это неправильно :)

+0

Старайтесь не использовать JQuery обещает, когда вы можете легко использовать гораздо лучшие библиотеки обещание. – Bergi

ответ

0

Мммм я вижу несколько ошибок вы решить все обещания, когда первый ребенок возвращается , вы должны подождать, пока весь ваш дочерний каталог не закончит соответствующие обещания, и ваша глобальная переменная не будет внутренней, посмотрите этот пример с изменениями:

function _processEntries(dirPath) { 
    var result = []; 
    var dirEntry = new NativeFileSystem.DirectoryEntry(dirPath), deferred = new $.Deferred(); 

    /*async call*/ 
    dirEntry.createReader().readEntries(
     function (entries) { 
      var promises = []; 
      for (var i = 0; i < entries.length; i++) { 
       if (entries[i].isDirectory) { 
        promises.push(_processEntries(entries[i].fullPath)); 
       } else { 
        result.push(entries[i].fullPath); 
       } 
      } 

      if(promises.length === 0) { 
       deferred.resolve(result); 
      } else { 
       $.when.apply($,promises).done(function() { 
       result.concat(arguments); 
       deferred.resolve(result); 
       }) 
      } 
     }, 
     function (error) { 
      console.log("Failed while reading dir:", error); 
     } 
    ); 
    return deferred.promise(); 
} 
0

когда я разрешаю обещание

Сразу, когда асинхронный вызов закончился. В противном случае у вас будет deferred antipattern. Избегая этого, вы можете работать с обещаниями повсюду и использовать с ними надлежащую композицию.

Кроме того, вы не должны инициализировать переменную result вне функции _processEntries - у вас возникнут проблемы с вызовом функции несколько раз.

function getDirectoryEntries(dirPath) { 
    // a promise helper function 
    var dirEntry = new NativeFileSystem.DirectoryEntry(dirPath), 
     deferred = new $.Deferred(); 
    dirEntry.createReader().readEntries(deferred.resolve, deferred.reject); 
    return deferred.promise(); 
} 
function _processEntries(dirPath) { 
    return getDirectoryEntries(dirPath).then(function (entries) { 
     var promises = []; 
     for (var i = 0; i < entries.length; i++) { 
      if (entries[i].isDirectory) { 
        promises.push(_processEntries(entries[i].fullPath)); 
      } else { 
        promises.push($.when(entries[i].fullPath)); 
      } 
     } 
     return $.when.apply($, promises).then(function() { 
      return [].concat.apply([], arguments); 
     }); 
    }); 
} 

Зов это следующим образом:

_processEntries("C:/Users/abc").then(function(result){ 
    console.log("FILES ARRAY:",result); 
}, function (error) { 
    console.log("Failed while reading dir:", error); 
}); 

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

  • Нет связанных вопросов^_^