2013-11-22 65 views
4

我正在使用CEF在javascript中構建原生桌面應用程序,並且我有API來從CEF訪問文件系統。我有一個senario, 其中我需要獲取特定目錄中所有文件的名稱(可能是目錄樹)。我需要得到結果數組,我正在使用jQuery的承諾。我不明白的是:我什麼時候解決承諾以獲得最終結果數組?遞歸函數內的Asynchronus調用

/*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。避免這種情況,你可以在任何地方使用諾言,並使用適當的組合。

此外,您不應該在_processEntries函數之外初始化您的result變量 - 您會在多次調用函數時遇到大問題。

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