Angularjs 重用http调用的结果
我有以下用例:Angularjs 重用http调用的结果,angularjs,typescript,http,Angularjs,Typescript,Http,我有以下用例: 两个可视化网格使用两种方法加载要显示的数据。这些方法由网格自动调用,此部分不能更改,这是设计的: loadDataForGrid1 = (params: any): any => { return this.httpService.getData().then((response) => { return response.dataGrid1; }, (err) => {
两个可视化网格使用两种方法加载要显示的数据。这些方法由网格自动调用,此部分不能更改,这是设计的:
loadDataForGrid1 = (params: any): any => {
return this.httpService.getData().then((response) => {
return response.dataGrid1;
}, (err) => {
});
}
loadDataForGrid2 = (params: any): any => {
return this.httpService.getData().then((response) => {
return response.dataGrid2;
}, (err) => {
});
}
一切正常,但我的问题是性能。由于getData方法执行的http请求非常庞大,因此不能像Im现在这样调用它两次。有没有办法只打一个电话就解决这个问题?比如缓存数据,以便第二次调用可以重用它们
我正在使用typescript和angularjs
编辑:
这样的操作不起作用,因为当网格加载数据时,结果将不可用:
result: any;
// called at the beginning, for example contructor
loadData = (params: any): any => {
return this.httpService.getData().then(result => {
this.result = result;
});
}
loadDataForGrid1 = (params: any): any => {
return this.result.gridGrid1;
}
loadDataForGrid2 = (params: any): any => {
return this.result.gridGrid2;
}}
this.httpService.getData().then((response) => {
this.data1 = response.dataGrid1;
this.data2 = response.dataGrid2;
// other properties here...
this.isReady= true;
}, (err) => {
});
使用@georgeawg建议的答案生成以下javascript(执行2次调用)
您始终可以将数据数组中的数据存储在SPA页面上的变量中。如果要在不同页面上使用数据,可以使用localStorage在客户端“缓存”数据
localStorage.set("mydata", response.dataGrid1);
localStorage.get("mydata");
仅供参考,我认为您使用的不是typescript,而是本机javascript:-)
--
你为什么不这样做,或者我错过了什么
$scope.gridData = {};
loadDataForGrid1 = (params: any): any => {
return this.httpService.getData.then((response) => {
$scope.gridData = response;
}, (err) => {
}).finally(function(){
console.log($scope.gridData.gridData1);
console.log($scope.gridData.gridData2);
});
}
您可以做的是将返回的变量存储到服务变量中,然后检查它是否已经存在
dataGrid;
loadDataForGrid1 = (params: any): any => {
if(!this.dataGrid) {
return this.httpService.getData.then((response) => {
this.dataGrid = response;
return this.dataGrid.dataGrid1;
}, (err) => {
});
}
return this.dataGrid.dataGrid1;
}
loadDataForGrid2 = (params: any): any => {
if(!this.dataGrid) {
return this.httpService.getData().then((response) => {
this.dataGrid = response;
return this.dataGrid.dataGrid2;
}, (err) => {
});
}
return this.dataGrid.dataGrid2;
}
这样的办法应该行得通。每次调用
loadDataForGrid1
或loadDataForGrid2
时,您将首先检查数据是否已经存在-因此您只进行一次API调用。解决方案是缓存承诺并重新使用它:
var promiseCache;
this.loadDataForGrid1=(参数)=>{
promiseCache=promiseCache | | this.httpService.getData();
返回promiseCache。然后(结果=>{
返回result.grid1;
});
}
this.loadDataForGrid2=(参数)=>{
promiseCache=promiseCache | | this.httpService.getData();
返回promiseCache。然后(结果=>{
返回result.grid2;
});
}
由于服务立即返回承诺,因此它避免了
第二个XHR在第一个XHR从服务器返回数据之前启动
你的意思是这将是一个javascript解决方案?但是如何使用typescript呢 JavaScript支持私有变量 在TypeScript中,这可以这样表示:
class MyClass {
doSomething: () => number;
constructor() {
var myPrivateVar = 3;
this.doSomething = function () {
return myPrivateVar++;
}
}
}
所以,几个小时后,我得出了以下解决方案。这是一个有点黑客,但它的工作 在初始化(构造函数等)中,我正在加载数据:
result: any;
// called at the beginning, for example contructor
loadData = (params: any): any => {
return this.httpService.getData().then(result => {
this.result = result;
});
}
loadDataForGrid1 = (params: any): any => {
return this.result.gridGrid1;
}
loadDataForGrid2 = (params: any): any => {
return this.result.gridGrid2;
}}
this.httpService.getData().then((response) => {
this.data1 = response.dataGrid1;
this.data2 = response.dataGrid2;
// other properties here...
this.isReady= true;
}, (err) => {
});
然后我写了一个丑陋的等待方法
wait(): void {
if (this.isReady) {
return;
} else {
setTimeout(this.wait, 250);
}
}
最后,我的两种方法是这样的
loadDataForGrid1 = (params: any): any => {
this.wait();
return this.$q.resolve(this.data1);
}
loadDataForGrid2 = (params: any): any => {
this.wait();
return this.$q.resolve(this.data2);
}
它是typescript,但因为这个对象非常复杂,刚刚返回到网格,所以它不是类型化的:)我不确定您的解决方案是否适用于我,因为我必须为每个请求获取新的数据:用户使用两个网格登录到我的页面,而在这里,我只需要一个调用(而不是两个)。刷新页面应该会执行一个新的调用。为什么不将完整的响应存储在范围中的变量中呢?我编辑了我的回复,我不确定是否理解你的答案,但可能是因为我对javascript了解不够。我的两个函数loadDataForGrid1和loadDataForGrid02是自动调用的(可能是并行调用的),我不知道顺序是什么?因此,仅对第一个方法执行
return$scope.gridData.dataGrid1
,对第二个方法执行return$scope.gridData.dataGrid2
,将不起作用,因为此时结果不在那里?在您的示例中,您将调用同一个方法两次(this.httpService.getData),但每次调用都会得到不同的属性(gridData1和gridData2)。因此,我假设dat one调用一次只提供两个gridData属性?我添加了一个不起作用的示例,也许这有助于理解我的意思,以及在不调用getData()的情况下如何处理第二个网格再次调用方法?@Bidou能否请您更具体一点?您有两个服务调用同一个端点,但您只想调用该端点一次?那么为什么您有两个方法?并回答您的问题-然后在loadDataForGrid2中执行相同的签入操作(检查this.dataGrid1或this.dataGrid2-您需要调用什么)但是loadDataForGrid2正在加载(相同)响应的另一个属性:response.DataGrid2再次检查编辑。这种方法会起作用,或者至少给你一个方法。我认为它不会起作用,因为dataGrid变量需要一些时间来设置(比如一秒钟)。所以当你测试if(!This.dataGrid)
两次都会得到一个错误的结果,这将生成两个调用。顺便说一句,downvote不是来自我……看起来很有希望……只是测试了它,但不幸的是它生成了两个调用。我的理解是:假设第一个调用是loadDataFromGrid1
。缓存为空,因此它从getData()返回承诺然后在调用then()时提取数据,然后调用loadDataFromGrid2
,这次设置缓存,但下一行调用then()
方法,它执行承诺并生成第二个调用,对吗?就像您编写的那样,缓存承诺而不是结果!因此它被执行两次。.getData()
方法只能调用一次。该技术在JavaScript中工作。不确定它为什么不在这里工作。看看TypeScript编译器如何将其转换为JavaScript会很有帮助。我在问题中添加了生成的JavaScript,并更新了问题以使用JavaScript。你的意思是这将是一个JavaScript解决方案?但如何做到这一点那么用打字机?