The task is the following. I need to delete folder and it's content using rmdir from fs2 library. It returns deffered promise object. After it complete I need to create folder again. And function should return promise as well for further chaining.
任务如下。我需要从fs2库中删除文件夹和它的内容。它返回deffered promise对象。完成后,我需要再次创建文件夹。而功能也应回报承诺,以作进一步的链接。
The code I have right now is like this:
我现在的代码是这样的:
function clearOutputDir() {
var def = deferred();
var def2 = deferred();
if (fs.existsSync(outputFolder)) {
def.resolve(fs2.rmdir(outputFolder, {recursive: true, force: true}));
} else {
def.resolve();
}
def2.resolve(def.promise.then(function () {
return deferred.promisify(fs.mkdir)(outputFolder);
}));
return def2.promise;
}
Looks like it works, but it's ugly as hell. Can it be done simpler without def and def2?
看起来很管用,但它太丑了。没有def和def2,它能做得更简单吗?
2 个解决方案
#1
2
Firstly, there's no need to create unresolved promises on your own, it's cleaner to work with those returned by fs2 functions and "then" them, Plynx solution is good hint in that case
首先,不需要自己创建未解决的承诺,使用fs2函数返回的承诺会更简单,在这种情况下,Plynx解决方案是很好的提示
Secondly, due to async nature of things (and of how file system functions internally works), you should not use fs.exists function, it's generally deprecated, and good idea is to not use it at all, but do what you want to do directly, and rely on eventual error codes. See: https://groups.google.com/forum/?fromgroups=#!topic/nodejs/gRRuly79oRc it sheds more light on this.
其次,由于事物的异步性(以及文件系统内部的工作方式),您不应该使用fs。存在函数,它通常被弃用,好主意是不使用它,而是直接做您想做的事情,并依赖于最终的错误代码。参见:https://groups.google.com/forum/?fromgroups= # !主题/nodejs/gRRuly79oRc它提供了更多的信息。
Getting to the solution: Instead of promisifing fs.mkdir, you can also use mkdir from fs2, as unless custom options are supplied it works exactly as (fallbacks to) fs.mkdir, and does what you want, returns promise.
找到解决方案:而不是推广fs。mkdir,您还可以从fs2中使用mkdir,除非提供自定义选项,否则它的工作方式与(回退到)fs完全相同。mkdir返回promise。
function clearOutputDir(outputFolder) {
return fs2.rmdir(outputFolder, { recursive: true, force: true }).then(null, function (e) {
// Ignore "No such dir" error, otherwise propagate further
if (e.code === 'ENOENT') return null;
throw e;
}).then(fs2.mkdir.bind(fs2, outputFolder));
}
fs2.mkdir will be run only if fs2.rmdir is succesful or dir didn't exist. I've used bind to pass it with outputFolder, it has same effect as:
fs2。mkdir仅在fs2中运行。rmdir是成功的或不存在的。我用bind来传递outputFolder,它的效果是:
function clearOutuputDir(outputFolder) {
...
}).then(function () { return fs2.mkdir(outputFolder); });
}
If you decide to use promisify, it's always better to reuse promisified version, and do not create it on each function call:
如果您决定使用promisify,最好重用promisified版本,不要在每次函数调用时都创建它:
var mkdir = deferred.promisify(fs.mkdir);
function clearOutputDir(outputFolder) {
...
}).then(function () { return mkdir(outputFolder); });
}
#2
1
Consider using final-fs library for this purpose. Take a look at it's chaining example - it's very clean.
考虑为此使用final-fs库。看看它的链接例子——它非常干净。
It uses when library for it's async calls so it's almost impossible to fall into callback hell. Chaining is very easy - it's done by returning a Promise in a resolve function.
它使用类库进行异步调用,因此几乎不可能陷入回调地狱。链接非常简单——它是通过在解析函数中返回一个承诺来完成的。
The code would look like that:
代码是这样的:
var ffs = require('final-fs');
/**
* @param {string} outputDir
* @returns {Promise}
*/
function clearOutputDir(outputDir) {
return ffs.exists(outputDir)
.then(function (exists) {
if (exists) {
return ffs.rmdirRecursive(outputDir);
}
})
.then(function () {
return ffs.mkdir(outputDir);
});
}
#1
2
Firstly, there's no need to create unresolved promises on your own, it's cleaner to work with those returned by fs2 functions and "then" them, Plynx solution is good hint in that case
首先,不需要自己创建未解决的承诺,使用fs2函数返回的承诺会更简单,在这种情况下,Plynx解决方案是很好的提示
Secondly, due to async nature of things (and of how file system functions internally works), you should not use fs.exists function, it's generally deprecated, and good idea is to not use it at all, but do what you want to do directly, and rely on eventual error codes. See: https://groups.google.com/forum/?fromgroups=#!topic/nodejs/gRRuly79oRc it sheds more light on this.
其次,由于事物的异步性(以及文件系统内部的工作方式),您不应该使用fs。存在函数,它通常被弃用,好主意是不使用它,而是直接做您想做的事情,并依赖于最终的错误代码。参见:https://groups.google.com/forum/?fromgroups= # !主题/nodejs/gRRuly79oRc它提供了更多的信息。
Getting to the solution: Instead of promisifing fs.mkdir, you can also use mkdir from fs2, as unless custom options are supplied it works exactly as (fallbacks to) fs.mkdir, and does what you want, returns promise.
找到解决方案:而不是推广fs。mkdir,您还可以从fs2中使用mkdir,除非提供自定义选项,否则它的工作方式与(回退到)fs完全相同。mkdir返回promise。
function clearOutputDir(outputFolder) {
return fs2.rmdir(outputFolder, { recursive: true, force: true }).then(null, function (e) {
// Ignore "No such dir" error, otherwise propagate further
if (e.code === 'ENOENT') return null;
throw e;
}).then(fs2.mkdir.bind(fs2, outputFolder));
}
fs2.mkdir will be run only if fs2.rmdir is succesful or dir didn't exist. I've used bind to pass it with outputFolder, it has same effect as:
fs2。mkdir仅在fs2中运行。rmdir是成功的或不存在的。我用bind来传递outputFolder,它的效果是:
function clearOutuputDir(outputFolder) {
...
}).then(function () { return fs2.mkdir(outputFolder); });
}
If you decide to use promisify, it's always better to reuse promisified version, and do not create it on each function call:
如果您决定使用promisify,最好重用promisified版本,不要在每次函数调用时都创建它:
var mkdir = deferred.promisify(fs.mkdir);
function clearOutputDir(outputFolder) {
...
}).then(function () { return mkdir(outputFolder); });
}
#2
1
Consider using final-fs library for this purpose. Take a look at it's chaining example - it's very clean.
考虑为此使用final-fs库。看看它的链接例子——它非常干净。
It uses when library for it's async calls so it's almost impossible to fall into callback hell. Chaining is very easy - it's done by returning a Promise in a resolve function.
它使用类库进行异步调用,因此几乎不可能陷入回调地狱。链接非常简单——它是通过在解析函数中返回一个承诺来完成的。
The code would look like that:
代码是这样的:
var ffs = require('final-fs');
/**
* @param {string} outputDir
* @returns {Promise}
*/
function clearOutputDir(outputDir) {
return ffs.exists(outputDir)
.then(function (exists) {
if (exists) {
return ffs.rmdirRecursive(outputDir);
}
})
.then(function () {
return ffs.mkdir(outputDir);
});
}