我想遍历HTML 5文件系统中的所有文件,并在迭代完成后开始一些事件。由于这是异步+承诺,我很难尝试掌握其工作方式。
我正在使用angularJS,并创建了一个服务来封装html 5文件系统特定的功能。
这是递归函数:
function walkDirectory(path) { fileSystem.getFolderContents(path) //this is the services and it returns a promise containing all files in the current folder or directory .then(function(entries) { for (var i = 0; i < entries.length; i++) { if(entries[i].isFile) { console.log("is File: " + entries[i].name); //do something with file here } else if (entries[i].isDirectory) { console.log("is Dir: " + entries[i].name); walkDirectory(entries[i].fullPath); } } }); };
理想情况下,我想这样调用该函数,并让其返回一个承诺,一旦遍历所有文件,该承诺便会执行。
walkDirectory("/").then( function() { console.log(done); });
有什么技巧/想法可以实现吗?
一个想法是拥有一个诺言数组,并为每个文件/目录向该数组添加一个新的诺言。我的尝试:
function walkDirectory(path) { var defer= $q.defer(); var promises = [defer.promise]; fileSystem.getFolderContents(path) .then(function(entries) { for (var i = 0; i < entries.length; i++) { if(entries[i].isFile) { console.log("is File: " + entries[i].name); //do something with file here defer.resolve(); promises.push(defer.promise); } else if (entries[i].isDirectory) { console.log("is Dir: " + entries[i].name); promises.push(walkDirectory(entries[i].fullPath)); } } }); return $q.all(promises); }; walkDirectory("/").then(function() { console.log("done"); });
这似乎不起作用,因为完成状态永远不会显示在控制台中。
您要在填充数组之前返回它。
相反,您需要$q.all(promises)在then()回调内返回并返回外部诺言:
$q.all(promises)
then()
return fileSystem.getFolderContents(path).then(function(entries) { return $q.all(entries.map(function(e) { if (e.isFile) { // Do something return null; // Don't wait for anything } else { // Do something return walkDirectory(e.fullPath); } })); });