我是节点的新手,我目前正在努力寻找最有效的方法来创建一个构造取决于http查询结果的对象。在返回并成功解析查询之前,该对象是无用的,因此在没有初始化对象的情况下从构造函数返回感觉不对,但我读过有关节点的所有内容都说我应该保持异步。
我可以像这样同步写它(原谅伪代码)
function FooConfig(cfg_url) {
// use httpsync to get the response synchronously
var response = get(cfg_url);
if (response.is_good()) {
// parse response and set member data from response
this.bar = response.bar
} else {
// Raise an error
}
};
或异步
function FooConfig(cfg_url) {
// Use the regular http module and make the request asynchronously
var newCfg = this;
http.get(cfg_url, function(response) {
if (response.is_good()) {
newCfg.bar = respsonse.bar
} else {
// Raise an error
}
});
});
异步版本的问题在于,如果请求未完成,依赖于FooCfg实例的任何客户端代码都可能会失败。
即
var myCfg = new FooCfg('www.someurl.com/config')
// request is still pending
var myDependentObject = new DependsOnConfig(cfg); // Error, this neeeds myCfg.bar
这是一个可以同步的实例吗?这应该只在初始化节点应用程序时发生一次。
答案 0 :(得分:1)
我会使用Factory来做这件事。基本上,不是在构造函数中进行异步获取,而是在工厂方法中执行,并将获取的结果传递给构造函数。然后,通过回调传回新对象。
所以,你的构造函数可能看起来像这样:
function FooConfig(cfg_data) {
this.bar = cfg_data.bar
}
您的工厂方法看起来像:
var fooFactory(callback) {
http.get(cfg_url, function(response) {
if (response.is_good()) {
callback(null, new FooConfig(response)) // Here's the actual constructor call
} else {
callback(new Error("something bad happened"))
}
});
}
您可以这样称呼:
fooFactory(function(err, myCfg) {
if (err) {
// handle error
} else {
var myDependentObject = new DependsOnConfig(myCfg);
}
});
答案 1 :(得分:-1)
我会将构造和初始化分成两个不同的部分,并使初始化方法返回一个承诺,或至少回调。 when
初始化已完成,then
使用它。