对一个's的成功构建依赖于Nodejs中的http调用

Most idiomatic way to code an object who's successful construction depends on an http call in Nodejs

本文关键字:构建 成功 依赖于 Nodejs 调用 http 中的 一个      更新时间:2023-09-26

我是节点的新手,目前正在努力寻找最直观的方法来创建一个对象,该对象的构造取决于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

这是一个可以同步的实例吗?在初始化节点应用程序时,这种情况应该只发生一次。

我会使用工厂来实现这一点。基本上,与其在构造函数中进行异步获取,不如在工厂方法中进行,并将获取的结果传递给构造函数。然后,通过回调返回新对象。

所以,你的构造函数可能看起来像这样:

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

我会将构造和初始化分为两个不同的部分,并让初始化方法返回一个promise,或者至少返回一个回调。when初始化完成,then使用它。