Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript AngularJS promise正在缓存_Javascript_Angularjs_Promise_Deferred_Angular Promise - Fatal编程技术网

Javascript AngularJS promise正在缓存

Javascript AngularJS promise正在缓存,javascript,angularjs,promise,deferred,angular-promise,Javascript,Angularjs,Promise,Deferred,Angular Promise,我想我写的承诺是错误的,我不明白为什么它会缓存数据。发生的情况是,假设我以scott的身份登录。当应用程序启动时,它将连接到端点以获取设备名称和设备映射的列表。在这个时候它工作得很好 当我注销并且不刷新浏览器并且以其他用户身份登录时,scott在同一浏览器选项卡上检索到的设备名称会被新登录的用户看到。然而,我可以从我的Chrome的网络标签中看到端点被调用,并且它收到了正确的设备名称列表 所以我想在我的工厂中添加destroyDeviceListing函数,希望能够清除这些值。在注销期间调用此函

我想我写的承诺是错误的,我不明白为什么它会缓存数据。发生的情况是,假设我以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
函数非常相似,具体取决于您希望它做什么。