如何使Grunt等待任务完成后再运行另一个?

这是我的Gruntfile和输出 。

正如您在输出中看到的那样,有几个与asynchronous任务相关的问题:

  1. imagemin被称为,下一个直线前进。 这使得它的输出出现在任务的最后,有什么相当混乱的;
  2. build ,这是一个自定义任务,使用var done = this.async()并在完成命令后调用done() ; 但是,如果我单独运行任务,这只能正常工作。 用另一个任务运行它也会使其运行asynchronous;
  3. 随着build运行后, jasmine没有什么可testing,因此是无用的。

有没有办法解决这个问题?

我相信你的问题是这个任务:

 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()将被多次调用。 asynchronous被实现为一个简单的标志(真/假),并被打算被调用一次。 第一个done()调用允许任何后续的任务运行。

有很多方法可以将呼叫转移到asynchronous并完成循环。 快速谷歌search如: nodejs how to callback when a series of async tasks are complete将给你一些额外的select。 几个快速(&肮脏)的例子:

 // 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文档 :

如果任务是asynchronous的,则必须调用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 });