我在服务器上有一个文件夹层次结构。我想以异步方式和递归方式遍历此层次结构,并在找到文件时调用自定义方法。
目前,我的代码如下所示:
searchFile(root, handleFile);
// loop over all folders recursively, then handle files
function searchFile(item, callbackWhenFile) {
if (itIsFolder(item)) {
$http.get("api.call.com/children/" + item.id)
.then(function (children) {
angular.forEach(children,
function (child) {
searchFile(child, callbackWhenFile);
});
});
}
else {
// this is not a folder, so this is a file
callbackWhenFile(item);
}
}
使用回调而不是承诺的事实并不是一件好事。
但是我试图找到一种方法让它无条件地与承诺一起工作。
在理想的解决方案中,我想做类似的事情:
searchFile(root).then(function (file) {
handleFile(file)
});
我看了$ q.all,$ q.when,但似乎没有任何东西适合这种情况。我们不知道文件数量会导致问题变得困难。
任何人都知道如何解决这个问题?
修改答案
Promises are not the way to go.
使用RxJS和可观察对象,可以写成:
getFileStream(root).subscribe(function (file) {
handleFile(file);
});
function getFileStream(root) {
var source = Rx.Observable.create(function (observer) {
observeFiles(observer, root);
});
return source;
}
function observeFiles(observer, item) {
if (itIsFolder(item)) {
$http.get("api.call.com/children/" + item.id)
.then(function (children) {
angular.forEach(children,
function (child) {
searchFile(observer, child);
});
});
}
else {
observer.onNext(item);
}
}
答案 0 :(得分:3)
承诺只能解析为单个值。该值可以是对象或数组,但最后,它是单个值 - 而不是流。
您的“理想解决方案”被定义为确实生成了流,但这是不可能的。
你可以:
答案 1 :(得分:-1)
以下代码可以解决这个问题:
searchFile(root).then(function (files) {
function (files) {
angular.forEach(files,
function (file) {
handleFile(file);
});
});
});
// loop over all folders recursively, then handle files
function searchFile(item) {
var deferred = $q.defer();
var files = [];
if (itIsFolder(item)) {
$http.get("api.call.com/children/" + item.id)
.then(function (children) {
angular.forEach(children,
function (child) {
searchFile(child).then(
function (files) {
angular.forEach(files,
function (file) {
files.add(file);
});
});
});
deferred.resolve(files);
});
}
else {
files.add(item);
deferred.resolve(files);
}
return deferred.promise;
}