在另一个任务之前asynchronous运行grunt任务

我有一个gruntfile设置,以便我可以开发我的本地angularjs前端,同时转发所有api请求到一个Java中间层托pipe在networking上单独。

这工作很好,除了服务器的位置每隔几天更改,我必须不断更新最新的服务器位置gruntfile。

最新的服务器位置可以通过转发到正确位置的URL缩短服务find,所以我可以使用这个grunt task / 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); } } }); }); 

当然这是asynchronous的,当我运行它时,grunt已经在请求完成的时候设置了代理。

我怎样才能同步运行这个nodejs请求或者阻塞grunt直到它完成? 这只是发展,所以哈克解决scheme欢迎。

谢谢

编辑:

伟大的答案科里,大多已经解决了问题,因为现在等待任务完成之前继续。 最后一个问题是我无法从initConfig访问该configuration来设置代理,因为initConfig首先运行:

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

这篇文章( initConfig()中的Access Gruntconfiguration数据 )概述了这个问题,但我不确定如何在任务外同步运行请求?

EDIT2 [解决]:

Corys回答+这篇文章编程传递参数咕噜任务? 为我解决了这个问题。

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

您可以轻松地asynchronous运行任务,并通过gruntconfiguration对象在任务之间共享数据,而不是同步运行任务 。

1.asynchronous运行任务

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

asynchronous任务:

 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()位(在上面的代码中)可能是在任务之间共享值的最简单的方法。 由于所有任务共享相同的gruntconfiguration,只需在config上设置一个属性,然后通过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任务具有configuration依赖关系。 这在很长一段时间内任务不变(非常常见)以及错综复杂的情况下很有用。 如果您决定更改asynchronous任务(重命名variables?dev_proxyHost,prod_proxyHost?),以下任务将优雅地通知您无法findproxyHost

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

3.你的代码是asynchronous的

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