如何让Grunt在运行另一个任务之前等待任务完成?

igo*_*s07 10 javascript asynchronous node.js gruntjs

这是我的Gruntfile输出.

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

  1. imagemin被召唤,下一个直接前进.这使得它的输出出现在任务的最后,这是非常混乱的;
  2. build,这是一个自定义任务,在完成命令后正在使用var done = this.async()和调用done(); 但是,如果我单独执行任务,这只能正常工作; 用另一个任务运行它也使它也运行异步;
  3. 随着build以后的运行,jasmine没有什么可以测试,因此是无用的.

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

dc5*_*dc5 8

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

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();
                    });
            }
    });
Run Code Online (Sandbox Code Playgroud)

如果您有多个文件夹,则会多次调用async()和done().Async实现为一个简单的标志(true/false),意味着要调用一次.第一个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');
    }
})();
Run Code Online (Sandbox Code Playgroud)

- 要么 -

// 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');
    }
})();
Run Code Online (Sandbox Code Playgroud)