正确的方式与JS使用承诺链

任务如下。 我需要使用fs2库中的rmdir来删除文件夹和内容。 它返回承诺对象。 完成后我需要再次创build文件夹。 而且函数还应该返回承诺,以便进一步链接。

我现在的代码是这样的:

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

看起来像是有用的,但是它很糟糕。 如果没有def和def2,它可以做得更简单吗?

首先,没有必要自己创build未解决的承诺,与由fs2函数返回的那些工作以及“然后”返回的工作更清晰,Plynx解决scheme在这种情况下是很好的暗示

其次,由于事物的asynchronous性(以及文件系统函数在内部的工作原理),你不应该使用fs.exists函数,它通常被弃用,好主意是根本不使用它,而是做你想做的事情直接,并依靠最终的错误代码。 请参阅: https : //groups.google.com/forum/? fromgroups =#!topic/ nodejs/ gRRuly79oRc它更多地阐明了这一点。

到达解决scheme:除了提供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.rmdir成功或者dir不存在时才会运行fs2.mkdir 。 我已经使用绑定outputFolder传递它,它具有相同的效果:

 function clearOutuputDir(outputFolder) { ... }).then(function () { return fs2.mkdir(outputFolder); }); } 

如果您决定使用promisify ,最好重用promisified版本,并且不要在每个函数调用中创build它:

 var mkdir = deferred.promisify(fs.mkdir); function clearOutputDir(outputFolder) { ... }).then(function () { return mkdir(outputFolder); }); } 

考虑为此目的使用final-fs库。 看看它的链接例子 – 非常干净。

它使用库时,它是asynchronous调用,所以几乎不可能陷入callback地狱。 链接非常简单 – 通过在parsing函数中返回一个Promise完成。

代码看起来像这样:

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