【问题标题】:How to make Grunt wait for a task to finish before running another?如何让 Grunt 在运行另一个任务之前等待任务完成?
【发布时间】:2013-03-22 01:23:01
【问题描述】:

这是我的Gruntfileoutput

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

  1. imagemin 被调用,下一个直接出现。这使得它的输出出现在任务的末尾,相当混乱;
  2. build,这是一个自定义任务,使用var done = this.async()并在完成命令后调用done();但是,这只有在我单独运行任务时才能正常工作;与其他任务一起运行使其也异步运行;
  3. build 稍后运行,jasmine 没有什么可测试的,因此毫无用处。

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

【问题讨论】:

  • 我从来没有遇到过 Grunt 的 this.async() 的问题。可能是另一项任务的不良副作用?您是否尝试过不使用 imagemin 的任务链?

标签: javascript node.js asynchronous gruntjs


【解决方案1】:

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

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

【讨论】:

  • 之前有人说过,但不知道如何解决。如果我将异步移出,文件夹创建将与其他任务一起发生。
  • 我已经更新了我的答案,提供了几个在所有工作完成后如何回调的示例。
  • 看起来很酷!虽然我已经离开这个项目很长一段时间了,但我认为它会工作得很好。看起来开发人员还修复了导致此问题的某种问题,但无论如何答案都很好。抱歉回复晚了!
【解决方案2】:

正如您在Grunt documentation 中看到的那样:

如果任务是异步的,则必须调用this.async方法来指示 咕噜咕噜地等着。它返回一个“完成”函数的句柄,该函数应该是 任务完成时调用。

一个简短的例子类似于:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-17
    • 1970-01-01
    • 1970-01-01
    • 2016-05-24
    • 1970-01-01
    • 1970-01-01
    • 2016-03-23
    相关资源
    最近更新 更多