javascript - Run grunt task asynchronously before another task - Stack Overflow

I have a gruntfile setup so that I can develop my local angularjs frontend while forwarding all api req

I have a gruntfile setup so that I can develop my local angularjs frontend while forwarding all api requests to a java middle tier hosted seperately on the network.

This works great except the location of the server changes every few days and I have to continuously update the gruntfile with the latest server location.

The latest server location can be found by a URL shortening service that forwards to the correct location, so I can fetch it with this grunt task/node.js code:

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

Of course this is asynchonous, and when I run it, grunt has already setup the proxy by the time the request pletes.

How can I run this nodejs request synchronously or block grunt until it pletes? This is just for development so hacky solutions weled.

Thanks

EDIT:

Great answer Cory, that has mostly solved the problem as grunt now waits for the task to plete before continuing. One last issue is that I can't access that config from the initConfig for setting the proxy as initConfig runs first:

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

This post (Access Grunt config data within initConfig()) outlines the issue but I'm not sure how I could run the request synchronously outside of a task?

EDIT2 [solved]:

Corys answer + this post Programmatically pass arguments to grunt task? solved the issue for me.

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

I have a gruntfile setup so that I can develop my local angularjs frontend while forwarding all api requests to a java middle tier hosted seperately on the network.

This works great except the location of the server changes every few days and I have to continuously update the gruntfile with the latest server location.

The latest server location can be found by a URL shortening service that forwards to the correct location, so I can fetch it with this grunt task/node.js code:

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

Of course this is asynchonous, and when I run it, grunt has already setup the proxy by the time the request pletes.

How can I run this nodejs request synchronously or block grunt until it pletes? This is just for development so hacky solutions weled.

Thanks

EDIT:

Great answer Cory, that has mostly solved the problem as grunt now waits for the task to plete before continuing. One last issue is that I can't access that config from the initConfig for setting the proxy as initConfig runs first:

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

This post (Access Grunt config data within initConfig()) outlines the issue but I'm not sure how I could run the request synchronously outside of a task?

EDIT2 [solved]:

Corys answer + this post Programmatically pass arguments to grunt task? solved the issue for me.

module.exports = function(grunt) {
[...]
    grunt.initConfig({
        connect: {
           proxies: [{
                host: '<%= proxyHost %>',
Share Improve this question edited May 23, 2017 at 11:46 CommunityBot 11 silver badge asked Dec 16, 2014 at 17:24 AidanAidan 2251 gold badge3 silver badges11 bronze badges 0
Add a ment  | 

1 Answer 1

Reset to default 9

Instead of running the task synchronously, you can easily run the task asynchronously & share data between tasks through the grunt config object.


1. Run a task asynchronously

To run a task asynchronously, you must first inform Grunt that the task is going to be async by calling this.async() This async call returns a "done function" that you'll use to tell Grunt whether the task has passed or failed. You can plete the task by passing the handler true and fail it by passing it an error, or false.

Async Task:

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. Share data between tasks

That grunt.config.set() bit (in the code above) is probably the easiest way to share values between tasks. Since all tasks share the same grunt config, you simply set a property on the config and then read it from the following tasks via grunt.config.get('property')

Following Task

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

The grunt.config.requires bit will inform grunt that the task has config dependencies. This is useful in scenarios where tasks go untouched for a long time (very mon) and the intricacies are forgotten about. If you decide on changing the async task (rename the variable? dev_proxyHost, prod_proxyHost?) the following task will gracefully inform you that proxyHost could not be found.

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


3. Your code, async

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+")"));
        }
    });
});

Then from your proxy task, you can retrieve this proxyHost value via the following

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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745095498a4610952.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信