2

任务如下。我需要使用fs2库中的 rmdir 删除文件夹及其内容。它返回延迟的承诺对象。完成后,我需要再次创建文件夹。并且函数也应该返回承诺以进行进一步的链接。

我现在的代码是这样的:

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 可以更简单吗?

4

2 回答 2

2

首先,不需要自己创建未解决的承诺,使用 fs2 函数返回的承诺并“然后”处理它们会更干净,在这种情况下,Plynx 解决方案是一个很好的提示

其次,由于事物的异步性质(以及文件系统内部功能的工作方式),您不应该使用fs.exists功能,它通常已被弃用,最好不要使用它,而是做您想做的事直接,并依赖最终的错误代码。请参阅:https ://groups.google.com/forum/?fromgroups=#!topic/nodejs/gRRuly79oRc它更清楚地说明了这一点。

获得解决方案:您也可以使用 fs2 中的 mkdir 而不是承诺fs.mkdir,因为除非提供自定义选项,否则它的工作方式与fs.mkdir完全一样(回退到) ,并且执行您想要的操作,返回承诺。

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 。我已经使用bind将它与outputFolder一起传递,它与以下效果相同:

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

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

var mkdir = deferred.promisify(fs.mkdir);
function clearOutputDir(outputFolder) {
    ...
   }).then(function () { return mkdir(outputFolder); });
}
于 2013-02-02T13:23:45.953 回答
1

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

它使用when库进行异步调用,因此几乎不可能陷入回调地狱。链接非常简单——它通过在 resolve 函数中返回一个 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);
        });
}
于 2013-04-29T19:59:29.660 回答