Javascript AngularJS promise正在缓存
我想我写的承诺是错误的,我不明白为什么它会缓存数据。发生的情况是,假设我以scott的身份登录。当应用程序启动时,它将连接到端点以获取设备名称和设备映射的列表。在这个时候它工作得很好 当我注销并且不刷新浏览器并且以其他用户身份登录时,scott在同一浏览器选项卡上检索到的设备名称会被新登录的用户看到。然而,我可以从我的Chrome的网络标签中看到端点被调用,并且它收到了正确的设备名称列表 所以我想在我的工厂中添加destroyDeviceListing函数,希望能够清除这些值。在注销期间调用此函数。然而,这没有帮助。下面是我的工厂Javascript AngularJS promise正在缓存,javascript,angularjs,promise,deferred,angular-promise,Javascript,Angularjs,Promise,Deferred,Angular Promise,我想我写的承诺是错误的,我不明白为什么它会缓存数据。发生的情况是,假设我以scott的身份登录。当应用程序启动时,它将连接到端点以获取设备名称和设备映射的列表。在这个时候它工作得很好 当我注销并且不刷新浏览器并且以其他用户身份登录时,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 delferredload
。由于承诺只表示一个异步结果,因此延迟的结果也只能解决一次。您需要为每个请求创建一个新的延迟-尽管您根本不需要,但您可以使用您已经拥有的承诺
如果不需要任何缓存,则模块中不应包含全局延迟加载
、隔离加载
和\u设备集合
变量。照办
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;
},
…
};
你希望它做缓存吗?不,我不喜欢缓存数据。我需要使用promise,以确保数据已经到达,并且我可以调用下一个函数或代码。promise一旦解析就不能再次解析为其他值。在destroy函数中,再次创建承诺
deferredLoad=$q.defer()
好的,我会试试。很高兴知道,我没有意识到这一点。:)我在destroy函数中添加了deferredLoad=$q.defer()。我重新加载了我的浏览器,以便它获得最新的代码。但是我仍然从以前登录的用户那里得到旧值。是的,正如Chandermani前面提到的,我只有一个延迟变量。我没有意识到。现在试试:)刚注意到你更新了答案。如果我们想更新缓存,我们将如何编写一个名为createNewDeviceListing()的新函数?我认为它与我发布的destroyDiviceListing
函数非常相似,具体取决于您希望它做什么。