在另一个任务之前异步运行grunt任务

10

我已经设置好了一个gruntfile,这样我就可以开发我的本地angularjs前端,同时将所有api请求转发到在网络上单独托管的java中间层。

这个方法很棒,但是服务器的位置每隔几天就会改变,我不得不不断更新gruntfile以获取最新的服务器位置。

最新的服务器位置可以通过URL缩短服务找到,该服务将其转发到正确的位置,因此我可以使用此grunt任务/node.js代码获取它:

grunt.registerTask('setProxyHost', 'Pings the url shortener to get the latest test server', function() {
    request('http://urlshortener/devserver', function(error, response, body) {
        if (!error) {
            var loc = response.request.uri.href;
            if (loc.slice(0, 7) === 'http://') {
                proxyHost = loc.slice(7, loc.length - 1);
            }
        }
    });
});

当然,这是异步的,当我运行它时,grunt已经设置了代理,直到请求完成。

如何同步运行此nodejs请求或阻止grunt直到它完成?这仅用于开发,所以可以使用hacky的解决方案。

谢谢

编辑:

Cory提供了很好的答案,基本上解决了问题,因为grunt现在等待任务完成后才继续。最后一个问题是,我无法从initConfig中访问该配置以设置代理,因为initConfig首先运行:

module.exports = function(grunt) {
[...]
    grunt.initConfig({
        connect: {
            proxies: [{
                host: grunt.config.get('proxyHost')

这篇帖子(Access Grunt config data within initConfig())概述了问题,但我不确定如何在任务之外同步运行请求?

编辑2 [已解决]:

Cory的答案和这篇文章Programmatically pass arguments to grunt task?解决了我的问题。

module.exports = function(grunt) {
[...]
    grunt.initConfig({
        connect: {
           proxies: [{
                host: '<%= proxyHost %>',
1个回答

8

不要同步执行任务,你可以通过调用 异步运行任务 并通过 grunt 配置对象在任务之间共享数据。


1. 异步运行任务

要异步运行任务,必须首先告诉 Grunt 该任务将是异步的,并调用 this.async()。这个异步调用返回一个“完成函数”,你将使用它告诉 Grunt 任务是否已经通过或失败。你可以通过传递处理程序 true 来完成任务并通过传递错误或 false 来使其失败。

异步任务:

module.exports = function(grunt) {
    grunt.registerTask('foo', 'description of foo', function() {
        var done = this.async();

        request('http://www...', function(err, resp, body) {
            if ( err ) {
                done(false); // fail task with `false` or Error objects
            } else {
                grunt.config.set('proxyHost', someValue);
                done(true); // pass task
            }
        });
    });
}

2. 在任务之间共享数据

grunt.config.set()(在上面的代码中)可能是在任务之间共享值最简单的方法。由于所有任务共享相同的 grunt 配置,因此您只需在配置上设置一个属性,然后通过grunt.config.get('property')从后续任务中读取它。

后续任务

module.exports = function(grunt) {
    grunt.registerTask('bar', 'description of bar', function() {
        // If proxy host is not defined, the task will die early.
        grunt.config.requires('proxyHost');
        var proxyHost = grunt.config.get('proxyHost');
        // ...
    });
}

grunt.config.requires会告诉grunt任务具有配置依赖性。在长时间不接触任务(非常普遍)并且细节被遗忘的情况下,这非常有用。如果您决定更改异步任务(重命名变量?dev_proxyHost,prod_proxyHost?),则以下任务将优雅地通知您无法找到proxyHost

Verifying property proxyHost exists in config...ERROR
>> Unable to process task. 
Warning: Required config property "proxyHost" missing. Use --force to continue.


3. 你的代码,异步执行

grunt.registerTask('setProxyHost', 'Pings the url shortener to get the latest test server', function() {
    var done = this.async(),
        loc,
        proxyHost;

    request('http://urlshortener/devserver', function(error, response, body) {
        if (error) {
            done(error); // error out early
        }

        loc = response.request.uri.href;
        if (loc.slice(0, 7) === 'http://') {
            proxyHost = loc.slice(7, loc.length - 1);
            // set proxy host on grunt config, so that it's accessible from the other task
            grunt.config.set('proxyHost', proxyHost);
            done(true); // success
        }
        else {
            done(new Error("Unexpected HTTPS Error: The devserver urlshortener unexpectedly returned an HTTPS link! ("+loc+")"));
        }
    });
});

然后从您的代理任务中,可以通过以下方式检索此proxyHost值

var proxyHost = grunt.config.get('proxyHost');

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接