创建具有该字段的对象取决于AJAX调用

时间:2017-05-23 18:27:16

标签: javascript ajax

我正在尝试实例化一个服务层类" foo"这将负责代表我的表示层将调用API调用到任何地方。但是,必要的资源是" foo"只有通过对不同的端点进行AJAX调用才能实现需求。

例如,考虑foo是否需要获取当前登录用户的accountId来完成请求。但是,accountId只能通过网络呼叫到终端" bar"。

因此,我需要用条形码链接foo的电话。

bar.getAccountId().then( (accountId) => { foo.getInformation(accountId) });

但这意味着只要foo需要发出请求,它就会被bar的网络呼叫阻止。如果我们知道一个事实,即在用户访问网站的时间内,accountId不会改变,那么我们将accountId存储到foo字段中是理想的。

即,在foo的构造函数中,我希望能够做到这样的事情:

construtor() { bar.getAccountId().then( (accountId) => {this._accountId = accountId });

现在只要foo需要拨打电话,我就可以简单地使用_accountId而不是对bar进行网络调用,只是简单地调用foo:

foo.getInformation() //we no longer need to supply an accountId, since it's cached inside foo.

但是,由于我们的构造函数现在正在进行AJAX调用,因此我们无法知道调用是否已完成。如果我们尝试这样做:

var foo = new Foo; foo.getInformation()

我们无法确定foo的构造函数是否收到了bar的回复。我想出的一个解决方法就是明确地在构造函数中缓存promise。 e.g:

//CLASS FOO
constructor() {
  this._promise = bar.getAccountId().then((accountId) => {
    this._accountId = accountId;
  })
}

getInformation() {
  if (this._promise.hasResolved()) {
    return makeNetworkCall(this._accountId)
  } else {
    this._promise.then(() => {
      return makeNetworkCall(this._accountId);
    })
  }
}

我想知道是否有一个现有的设计模式来解决这个问题,因为我确定它的情况很常见。

2 个答案:

答案 0 :(得分:1)

我会将请求放在getInformation()调用中,并让它缓存调用的结果。然后在将来的调用中,您可以检查缓存的值,并使用缓存的值将已解析的promise返回给调用者。

类似的东西:

//CLASS FOO
constructor() {
  this._accountId = null;
}

getInformation() {
  if (this._accountId !== null) {
      // If value cached, return resolved promise with value.
      return Promise.resolve(this._accountId);
  }

  // Otherwise, retrieve the value and cache it.
  return bar.getAccountId().then((accountId) => {
      this._accountId = accountId;
      return accountId;
  });
}

答案 1 :(得分:0)

一般来说,构造函数不是进行异步工作的好地方。它应该初始化对象并为其他功能留下繁重的负担。

您可以简单地创建一个init()方法来加载所有必要的数据并返回一个可以继续按预期使用的承诺:

var foo = new Foo; foo.init().then(()=> {
    // doMoreAsyncStuff();
});