我正在尝试为http请求做一个缓存工厂,因此它不会使服务器为同一请求做很多工作。但是看来我使用延迟“吞咽”数据的方式,我不知道为什么。
控制台输出如下:
提取的数据:
对象{状态:“确定”,数据:对象,错误消息:空,异常:空}
成功
未定义
ImportFactory:
factory("importFactory", function ($http, $q, loggingService) {
return{
fetchedData: [],
cacheTransport: function (transportsId, data) {
this.fetchedData.push({"transportsId": transportsId, "data": data});
},
getImport: function (transportsId) {
var factory = this;
var deferred = $q.defer();
var preFetchedTransport = this.findTransport(transportsId);
if (preFetchedTransport === null) {
console.log('fetching from backend');
return $http.post("/import/create/" + transportsId).then(function (data) {
console.log('data fetched:');
console.log(data);
factory.cacheTransport(transportsId, data);
deferred.resolve(data);
});
}
preFetchedTransport = deferred.promise;
return preFetchedTransport;
},
findTransport: function (transportsId) {
for (var i = 0; i < this.fetchedData.length; i++) {
var transportObj = this.fetchedData[i];
if (transportObj.transportsId === transportsId) {
return transportObj.data;
}
}
return null;
}
};
});
控制者
.controller('ImportController', function ($scope, $routeParams, importFactory){
$scope.transportId = $routeParams.id;
importFactory.getImport($scope.transportId).then(function (successData) {
console.log('success');
console.log(successData);
}, function (errorData) {
console.log('error');
console.log(errorData);
});
最佳答案
您基本上需要这样:Demo here.
var cachedPromises = {};
return {
getStuff: function(id) {
if (!cachedPromises[id]) {
cachedPromises[id] = $http.post("/import/create/" + id).then(function(resp) {
return resp.data;
});
}
return cachedPromises[id];
}
};
现在,当您获取该数据时,您可以进行操作,以后在访问时将对其进行更改。
myService.getStuff(whatever).then(function(data) {
data.foo = 'abc';
});
//elsewhere
myService.getStuff(whatever).then(function(data) {
console.log(data.foo); // 'abc'
});
这是一个执行此操作的演示,以及一个视图更新技巧(将数据绑定到数据之前,将对象绑定到视图),以及如何在缓存中单独更改数据的想法,以防万一。原始数据和变化中的数据。 http://jsbin.com/notawo/2/edit
记住要避免那种讨厌的诺言反模式。如果您已经有了承诺,请使用该承诺,而不要使用
$q
创建另一个承诺。 $http
已经返回了一个承诺,如果正确使用它,该承诺就可以满足您的任何需求。