我正在尝试实例化一个服务层类" 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);
})
}
}
我想知道是否有一个现有的设计模式来解决这个问题,因为我确定它的情况很常见。
答案 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();
});