正如您在输出中看到的,有几个与异步任务相关的问题:
imagemin
被调用,下一个直接向前。这使得它的输出出现在任务的末尾,相当混乱;build
,这是一个自定义任务,在完成命令后使用var done = this.async()
和调用;done()
但是,这只有在我单独运行任务时才能正常工作;与其他任务一起运行它也会使其异步运行;build
稍后运行,没有什么要测试的,因此jasmine
是无用的。
有没有办法解决这种行为?
正如您在输出中看到的,有几个与异步任务相关的问题:
imagemin
被调用,下一个直接向前。这使得它的输出出现在任务的末尾,相当混乱;build
,这是一个自定义任务,在完成命令后使用var done = this.async()
和调用;done()
但是,这只有在我单独运行任务时才能正常工作;与其他任务一起运行它也会使其异步运行;build
稍后运行,没有什么要测试的,因此jasmine
是无用的。有没有办法解决这种行为?
我相信你的问题在于这个任务:
grunt.registerTask('prepare-dist', 'Creates folders needed for distribution', function() {
var folders = ['dist/css/images', 'dist/imgs/icons'];
for (var i in folders) {
var done = this.async();
grunt.util.spawn({ cmd: 'mkdir', args: ['-p', folders[i]] }, function(e, result) {
grunt.log.writeln('Folder created');
done();
});
}
});
如果您有多个文件夹,则 async() 和 done() 都将被多次调用。异步被实现为一个简单的标志(真/假),并且意味着被调用一次。第一个 done() 调用允许任何后续任务运行。
有很多方法可以将调用移至异步并完成循环。快速谷歌搜索类似的东西:nodejs how to callback when a series of async tasks are complete
会给你一些额外的选择。几个快速(和肮脏)的例子:
// Using a stack
(function() {
var work = ['1','2','3','4','5']
function loop(job) {
// Do some work here
setTimeout(function() {
console.log("work done");
work.length ? loop(work.shift()) : done();
}, 500);
}
loop(work.shift());
function done() {
console.log('all done');
}
})();
- 或者 -
// Using a counter (in an object reference)
(function() {
var counter = { num: 5 }
function loop() {
// Do some work here
setTimeout(function() {
--counter.num;
console.log("work done");
counter.num ? loop() : done();
}, 500);
}
loop();
function done() {
console.log('all done');
}
})();
正如您在Grunt 文档中所读到的:
如果任务是异步的,则必须调用 this.async 方法来指示 Grunt 等待。它返回一个“完成”函数的句柄,当任务完成时应该调用该函数。
一个简短的例子类似于:
// Tell Grunt this task is asynchronous.
var done = this.async();
// Your async code.
fetchData(url).then( data => {
console.log(data);
done();
}).catch( error => {
console.err(error);
done(false); // false instructs Grunt that the task has failed
});