以下函数用于通过HTTP调用删除文件到嵌入式Web服务器。 Web服务器接受DELETE动词删除文件;它也适用于文件夹,但仅限于空。
我想创建一个递归询问文件夹内容的函数,将其全部删除然后删除该文件夹。 使用promises,我设法让它几乎完全起作用。 顶部路径“/”中的文件被删除,第一个文件夹“/ folder1 /”中的文件也被删除,但随后函数退出,而“/ folder1 /”为空,“/ folder2 /”未触及。 尝试使用Firefox 40和Chrome 45。 有人能发现任何错误吗?我已经好几天了......
我认为这可能与jQuery promises和标准promise的混合使用有关,而不是正确解析。
通过API调用询问文件夹内容,该API调用返回如下对象的数组:
[{"type": "dir", "name": ".", "size": "-"},
{"type": "dir", "name": "..", "size": "-"},
{"type": "dir", "name": "folder1", "size": "-"},
{"type": "dir", "name": "folder2", "size": "-"}
{"type": "file", "name": "file1", "size": "1211"},
{"type": "file", "name": "file2", "size": "1251"},]
这是主要功能。
function purgeSdcard() {
printMessage("WARNING: Purging SDcard");
function purgeCycle(fileList, path, file) {
return new Promise(function(resolve, reject) {
if (typeof(fileList) === 'undefined' || fileList.length === 0) resolve();
if (typeof(file) === 'undefined') file = 0;
if (file >= fileList.length) resolve();
if (fileList[file].type === "dir") { // Directory
if (fileList[file].name === "." || fileList[file].name === ".." || fileList[file].name === "system volume information") {
return purgeCycle(fileList, path, file + 1);
}
else {
return purge(path + fileList[file].name + "/")
.then(function(res) {
return deleteFile(path + fileList[file].name);
})
.then(function(res) {
console.log("purgeCycle(fileList, path, file + 1) " + fileList + path + file + 1);
return purgeCycle(fileList, path, file + 1);
});
}
}
else { // File
return deleteFile(path + fileList[file].name).then(
function(res) {
return purgeCycle(fileList, path, file + 1);
});
}
});
}
function purge(path) {
if (typeof(path) === 'undefined') path = "/";
return getFileList(path).then(
function(fileList) {
return purgeCycle(fileList, path);
});
}
purge();
}
function getFileList(path, onDone) {
if (typeof(path) === 'undefined') path = "/";
return Promise.resolve($.ajaxQueue({
url: path + "?dir",
type: "GET",
dataType: "json"
}).done(function() {
console.log("getFileList: " + path);
if (typeof(onDone) === 'function') {
onDone();
}
})
.fail(function() {}));
}
function deleteFile(fileURL) {
printMessage("ST  - File delete: " + fileURL);
return Promise.resolve($.ajaxQueue({
url: fileURL,
type: "DELETE"
}).done(function() {
printMessage("OK  - File delete: " + fileURL);
})
.fail(function() {
printError("ERR - File delete: " + fileURL);
}));
}
答案 0 :(得分:0)
我认为您的猜测是正确的,这可能是jQuery Promises / Deferred对象与JS内置Promise之间的冲突。
Promise.resolve()
返回一个promise,该promise将解析为传递给函数的值,或者如果传递了promise,则返回到promise所解析的值。由于你传递的是jQuery.Deferred,它将解决这个问题,因此每当你调用getFileList(...).then(fileList)
时,你收到的fileList
实际上都是Deferred对象。
在这种情况下,您可以在代码中使用jQuery.Deferred对象,或者在Promise中包含$.ajaxQueue
,以便它兼容。您使用new Promise
,Promise.resolve
这一事实让我相信您没有投入jQuery.Deferred
,所以这里是使用包装版本的相关代码段的示例$.ajaxQueue
:
function ajaxQueue(options) {
return new Promise(function (resolve, reject) {
$.ajaxQueue(options).done(function (val) {
resolve(val);
}).fail(function (err) {
reject(err);
});
});
}
// returns Promise that resolves to a jQuery deferred value.
function getFileList(path, onDone) {
if (typeof path === 'undefined') path = "/";
return ajaxQueue({
url: path + "?dir",
type: "GET",
dataType: "json"
}).then(function (result) {
console.log("getFileList: " + path);
if (typeof onDone === 'function') {
onDone();
}
// Pass along.
return result;
}).catch(function (err) { });
}
function deleteFile(fileURL) {
printMessage("ST  - File delete: " + fileURL);
return ajaxQueue({
url: fileURL,
type: "DELETE"
}).then(function (result) {
printMessage("OK  - File delete: " + fileURL);
// Pass along result.
return result;
}).catch(function (err) {
printError("ERR - File delete: " + fileURL);
});
}
常规JS Promise
和jQuery.Deferred
(除可用函数之外)的主要区别在于then
的返回值是传递给后续then
个调用的内容。因此,如果您只是记录getFileList
和deleteFile
中的内容,则传递结果非常重要。