AngularJS承诺正在缓存
AngularJS promise is caching
我想我的承诺写错了,我不明白它为什么要缓存数据。结果是,假设我以scott的身份登录。当应用程序启动时,它将连接到一个端点以获取设备名称和设备映射的列表。它目前运行良好。
当我注销而不刷新浏览器时,我以不同的用户身份登录,斯科特在同一浏览器选项卡上检索到的设备名称,会被新登录的用户看到。然而,我可以从Chrome的网络选项卡中看到,端点被调用,它收到了正确的设备名称列表。
因此,我考虑在工厂中添加destroyDeviceListing函数,希望能够清除这些值。此函数在注销过程中被调用。然而,这并没有起到任何作用。下面是我的工厂
app.factory('DeviceFactory', ['$q','User', 'DeviceAPI', function($q, User, DeviceAPI) {
var deferredLoad = $q.defer();
var isLoaded = deferredLoad.promise;
var _deviceCollection = { deviceIds : undefined };
isLoaded.then(function(data) {
_deviceCollection.deviceIds = data;
return _deviceCollection;
});
return {
destroyDeviceListing : function() {
_deviceCollection.deviceIds = undefined;
deferredLoad.resolve(_deviceCollection.deviceIds);
},
getDeviceIdListing : function() {
return isLoaded;
},
getDeviceIdMapping : function(deviceIdsEndpoint) {
var deferred = $q.defer();
var userData = User.getUserData();
// REST endpoint call using Restangular library
RestAPI.setBaseUrl(deviceIdsEndpoint);
RestAPI.setDefaultRequestParams( { userresourceid : userData.resourceId, tokenresourceid : userData.tokenResourceId, token: userData.bearerToken });
RestAPI.one('devices').customGET('', { 'token' : userData.bearerToken })
.then(function(res) {
_deviceCollection.deviceIds = _.chain(res)
.filter(function(data) {
return data.devPrefix != 'iphone'
})
.map(function(item) {
return {
devPrefix : item.devPrefix,
name : item.attributes[item.devPrefix + '.dyn.prop.name'].toUpperCase(),
}
})
.value();
deferredLoad.resolve(_deviceCollection.deviceIds);
var deviceIdMapping = _.chain(_deviceCollection.deviceIds)
.groupBy('deviceId')
.value();
deferred.resolve(deviceIdMapping);
});
return deferred.promise;
}
}
}])
下面是我的控制器的摘录,缩短和清洁版本
.controller('DeviceController', ['DeviceFactory'], function(DeviceFactory) {
var deviceIdMappingLoader = DeviceFactory.getDeviceIdMapping('http://10.5.1.7/v1');
deviceIdMappingLoader.then(function(res) {
$scope.deviceIdMapping = res;
var deviceIdListingLoader = DeviceFactory.getDeviceIdListing();
deviceIdListingLoader.then(function(data) {
$scope.deviceIDCollection = data;
})
})
})
好吧,整个应用程序只有一个var deferredLoad
。由于promise只代表一个异步结果,因此延迟的结果也只能解析一次。您需要为每个请求创建一个新的deferred——尽管您根本不需要创建一个deferred,但您可以使用现有的promise。
如果不需要任何缓存,则模块中不应该有全局deferredLoad
、isLoaded
和_deviceCollection
变量。只做
app.factory('DeviceFactory', ['$q','User', 'DeviceAPI', function($q, User, DeviceAPI) {
function getDevices(deviceIdsEndpoint) {
var userData = User.getUserData();
// REST endpoint call using Restangular library
RestAPI.setBaseUrl(deviceIdsEndpoint);
RestAPI.setDefaultRequestParams( { userresourceid : userData.resourceId, tokenresourceid : userData.tokenResourceId, token: userData.bearerToken });
return RestAPI.one('devices').customGET('', { 'token' : userData.bearerToken })
.then(function(res) {
return _.chain(res)
.filter(function(data) {
return data.devPrefix != 'iphone'
})
.map(function(item) {
return {
devPrefix : item.devPrefix,
name : item.attributes[item.devPrefix + '.dyn.prop.name'].toUpperCase(),
};
})
.value();
});
}
return {
destroyDeviceListing : function() {
// no caching - nothing there to be destroyed
},
getDeviceIdListing : function(deviceIdsEndpoint) {
return getDevices(deviceIdsEndpoint)
.then(function(data) {
return { deviceIds: data };
});
},
getDeviceIdMapping : function(deviceIdsEndpoint) {
return this.getDeviceIdListing(deviceIdsEndpoint)
.then(function(deviceIds) {
return _.chain(deviceIds)
.groupBy('deviceId')
.value();
});
}
};
}])
现在,要添加缓存,只需创建一个全局promise变量,并在创建请求后将promise存储在那里:
var deviceCollectionPromise = null;
…
return {
destroyDeviceListing : function() {
// if nothing is cached:
if (!deviceCollectionPromise) return;
// the collection that is stored (or still fetched!)
deviceCollectionPromise.then(function(collection) {
// …is invalidated. Notice that mutating the result of a promise
// is a bad idea in general, but might be necessary here:
collection.deviceIds = undefined;
});
// empty the cache:
deviceCollectionPromise = null;
},
getDeviceIdListing : function(deviceIdsEndpoint) {
if (!deviceCollectionPromise)
deviceCollectionPromise = getDevices(deviceIdsEndpoint)
.then(function(data) {
return { deviceIds: data };
});
return deviceCollectionPromise;
},
…
};
相关文章:
- 我的职位回报太快了,如何做出承诺
- 打破承诺链的好方法是什么
- 从函数返回角度承诺
- 如何在从浏览缓存加载页面时执行javascript
- ReactJS和SpringDataRest缓存问题可能与websocket有关
- 缓存谷歌地图数据
- 我怎样才能获得承诺的价值
- 延期承诺值未更新/解析/延期
- 在承诺链中处理早期回报的最佳方式
- 防止jQuery Mobile中的ajax缓存
- 承诺在非节点式回调上使用Bluebird
- image.onload事件和浏览器缓存
- 简单的ES6承诺问题-交换解决和拒绝参数
- 组合承诺和非承诺值
- 带有对象/原型的链式承诺(Q延期)
- 如何在不缓存外部的情况下将“this”传递到承诺中
- Javascript中的缓存和预取过期承诺
- AngularJS回调,复制$http的行为.将缓存转化为承诺
- AngularJS承诺正在缓存
- Javascript承诺,缓存&角