我有一个 gruntfile 设置,这样我就可以开发我的本地 angularjs 前端,同时将所有 api 请求转发到网络上单独托管的 java 中间层。
这很好用,除了服务器的位置每隔几天就会改变一次,我必须不断用最新的服务器位置更新 gruntfile。
最新的服务器位置可以通过转发到正确位置的 URL 缩短服务找到,所以我可以使用这个 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);
}
}
});
});
当然这是异步的,当我运行它时,grunt 已经在请求完成时设置了代理。
如何同步运行这个 nodejs 请求或阻止 grunt 直到它完成?这仅用于开发,因此欢迎使用 hacky 解决方案。
谢谢
编辑:
很好的答案科里,这主要解决了问题,因为 grunt 现在等待任务完成后再继续。最后一个问题是我无法从 initConfig 访问该配置以设置代理,因为 initConfig 首先运行:
module.exports = function(grunt) {
[...]
grunt.initConfig({
connect: {
proxies: [{
host: grunt.config.get('proxyHost')
这篇文章 (Access Grunt config data within initConfig()) 概述了这个问题,但我不确定如何在任务之外同步运行请求?
EDIT2 [已解决]:
Corys 回答 + 这篇文章 Programmatically pass arguments to grunt task?为我解决了这个问题。
module.exports = function(grunt) {
[...]
grunt.initConfig({
connect: {
proxies: [{
host: '<%= proxyHost %>',
最佳答案
您可以轻松地run the task asynchronously 而不是同步运行任务& 通过 grunt config 对象在任务之间共享数据。
1。异步运行任务
要异步运行任务,您必须首先通过调用 this.async()
通知 Grunt 该任务将是异步的告诉 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');
关于javascript - 在另一个任务之前异步运行 grunt 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27510379/