2013-03-31 203 views
8

这是我的Gruntfileoutput如何让Grunt在运行另一个任务之前等待任务完成?

正如你可以在输出中看到,有一对夫妇的相关异步任务的问题:

  1. imagemin被调用,下一个来直行。这使得它的输出出现在任务的最后,这很麻烦;
  2. build,这是一个自定义任务,使用var done = this.async()并在完成命令后调用done();但是,如果我单独运行任务,这只能正常工作;用其他任务运行它也会使其运行异步;
  3. 随着build运行后,jasmine没有什么可测试,因此是无用的。

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

+0

我从来没有与步兵的this.async问题()。可能是另一项任务的不良副作用?你有没有尝试你的任务链没有imagemin? –

回答

7

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

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(); 
        }); 
      } 
    }); 

如果你有多个文件夹,无论是异步()和()完成将被多次调用。异步是作为一个简单的标志(true/false)实现的,并且被调用一次。第一次完成()调用允许任何后续任务运行。

有很多方法可以将调用移动到异步并完成循环。快速谷歌搜索如: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'); 
    } 
})(); 
+0

我以前说过,但不知道如何解决。如果我将异步移出,文件夹创建将与其他任务一起发生。 – igorsantos07

+0

我已经更新了一些关于如何在所有工作完成时回调的示例。 – dc5

+0

看起来很酷!尽管我已经离开了这个项目很长一段时间了,但我认为它可以正常工作。看起来开发者也解决了一些导致这个问题的问题,但答案很好。这么晚才回复很抱歉! – igorsantos07

0

正如你可以在阅读Grunt documentation

如果一个任务是异步的,这必须调用.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 
});