我正在处理一个由其他人编写的grunt插件来接收硬编码的文件名(src和dest),但是我试图将其更改为能够被指向到具有通配模式的目录,并为" dest"指定输出文件夹。但是我遇到了async.each的问题,因为我的初始实现有一个嵌套的async.each。具体来说,我认为我在何时调用callback()时遇到问题。我在某个地方的某个循环中被挂断了。
这确实可以正常工作,因为文件是通过配置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开始,每个循环处理一个特定的"文件"源/目标。但是当我们使用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 :(得分: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.");
});