【问题标题】:Grunt Plugin- async.each with globbing patternGrunt Plugin- async.each 与 globbing 模式
【发布时间】:2014-09-16 02:44:43
【问题描述】:

我正在开发一个(由其他人)编写的 grunt 插件,用于接收硬编码的文件名(src 和 dest),但我正在尝试将其更改为能够指向一个目录一个 globbing 模式并为“dest”指定一个输出文件夹。但是我在使用 async.each 时遇到了问题,因为我的初始实现有一个嵌套的 async.each。具体来说,我认为我对何时调用回调()有疑问。我在某个地方被挂断了。

这确实像写的那样工作,因为文件是在配置 Gruntfile.js 的两种方式中正确创建的,但是以前工作的测试现在被破坏了。

我只是想知道如何构造第二个嵌套循环。也许不需要使用异步?

Gruntfile.js 应该能够被配置为:

myplugin: {
    dev: {
        files : {
            'src/business.html': 'src/test_src/business.test',
            ...
        }
    }
},

或作为通配模式(这是我要添加的)

myplugin: {
    dev: {
        src: ['src/test_src/*.test'],
        dest: 'output'
    }
},

插件以单个 async.each 开始,每个循环处理一个特定的“文件”src/dest。但是当我们使用通配模式时,只有一个外部循环,即模式,所以我需要第二个 async.each 来处理实际文件(大约有 11 个)。

grunt.registerMultiTask('myplugin', 'Compiles files using myplugin', function () {

    done = this.async();

    // Iterate over all specified file groups.
    async.each(this.files, function (fileGlob, cb) {
        var destination = fileGlob.dest;
        grunt.log.debug("FileGlob: " + fileGlob);

        async.each(fileGlob.src, function (filepath, callback) {
            if (notAPartial(filepath) && grunt.file.exists(filepath)) {
                if (filepath.match(/\.(test|html)$/)) {
                    grunt.log.debug('test compilation of ' + filepath);
                    compileMyFile(filepath, destination);
                } else {
                    // this callback is from the orig version
                    // i think it's causing problems with the nested async.each calls
                    callback(new Error("No handler for filetype: " + filepath));
                }
            }
        }, function(err) {
            if(err) done(err);
            else done();
        });
        cb();
    }, function(err) {
        if(err) done(err);
        else done();
        grunt.log.ok("Compiled " + count + " files.");
    });
})

【问题讨论】:

    标签: javascript node.js asynchronous gruntjs npm


    【解决方案1】:

    看起来您的回调有点不合适。 async.each 的签名是:async.each(arrayOfThings, callbackPerThing, callbackWhenWeGotThroughAllThings)

    对于嵌套async.each 语句,我喜欢根据回调的作用来命名回调,以避免嵌套时混淆,例如:

    var done = this.async();
    async.each(this.files, function(fileGlob, nextGlob) {
      async.each(fileGlob.src, function(filepath, nextFile) {
        doSomethingAsync(function() {
          // Continue to the next file
          nextFile();
        });
      }, function() {
        // When we are done with all files in this glob
        // continue to the next glob
        nextGlob();
      });
    }, function() {
      // When we are done with all globs
      // call done to tell the Grunt task we are done
      done();
    });
    

    在上述情况下,您不需要内部 async.each 是对的。您也不需要外部async.each,因为所有操作似乎都不是异步的。您可以更简单地执行以下操作:

    grunt.registerMultiTask('myplugin', 'Compiles files using myplugin', function () {
      this.files.forEach(function(fileGlob) {
        var destination = fileGlob.dest;
        grunt.log.debug("FileGlob: " + fileGlob);
    
        fileGlob.src.forEach(function(filepath) {
          if (notAPartial(filepath) && grunt.file.exists(filepath)) {
            if (filepath.match(/\.(test|html)$/)) {
              grunt.log.debug('test compilation of ' + filepath);
              compileMyFile(filepath, destination);
             } else {
               grunt.log.error("No handler for filetype: " + filepath);
             }
           }
        });
      });
    
      grunt.log.ok("Compiled " + count + " files.");
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-16
      • 2010-12-27
      • 1970-01-01
      相关资源
      最近更新 更多