2014-07-24 16 views
0

我的工作是寫(別人)咕嚕插件接收硬編碼的文件名(SRC和dest),但我試圖將其更改爲能夠指向一個具有匹配模式的目錄,併爲「dest」指定一個輸出文件夾。但是我對async.each有問題,因爲我的初始實現有一個嵌套的async.each。具體來說,我想我什麼時候調用callback()會有問題。我在某個地方掛了一圈。咕嚕Plugin- async.each與文件名匹配模式

這樣確實可以書面因爲文件被創建配置Gruntfile.js正確兩種方式,但現在的以前工作的測試被打破。

我只是想知道如何組織第二嵌套循環。也許這不需要使用異步?

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

或作爲文件名匹配模式(這是我加入的)

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

該插件開始了:

的Gruntfile.js應該能夠爲要config'd與一個單一的async.each,每個循環處理特定的「文件」src/dest。但是當我們使用globbing模式時,只有一個外部循環模式,所以我需要第二個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."); 
    }); 
}) 

回答

0

看起來你的回調有點不合適。 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."); 
});