在AngularJS服务中caching承诺对象
我想要使用Promises在AngularJS中实现一个静态资源的dynamic加载。 问题:我有几个组件可能(或不是,取决于哪些显示,因此dynamic)需要从服务器获取静态资源。 一旦加载,它可以被caching整个应用程序的生活。
我已经实现了这个机制,但是我对Angular和Promises是新的,我想确定这是否是一个正确的解决scheme。
var data = null; var deferredLoadData = null; function loadDataPromise() { if (deferredLoadData !== null) return deferredLoadData.promise; deferredLoadData = $q.defer(); $http.get("data.json").then(function (res) { data = res.data; return deferredLoadData.resolve(); }, function (res) { return deferredLoadData.reject(); }); return deferredLoadData.promise; }
所以,只有一个请求被创build,接下来所有对loadDataPromise()的调用都会返回第一个作出的承诺。 好像在进行中的要求或者前一个已经完成的要求。
但是cachingPromise是一个好的解决scheme吗?
这是正确的方法吗?
是。 对返回的函数使用memoisation有望实现一种通用的技术,以避免重复执行asynchronous(通常是昂贵的)任务。 这个承诺使caching变得容易,因为不需要区分正在进行的操作和已经完成的操作,它们都被表示为(相同的)对结果值的承诺。
这是正确的解决scheme吗?
不是。那个全局data
variables和undefined
的分辨率并不是承诺如何工作的。 相反,用结果data
履行承诺! 这也使编码更容易:
var dataPromise = null; function getData() { if (dataPromise == null) dataPromise = $http.get("data.json").then(function (res) { return res.data; }); return dataPromise; }
然后,而不是loadDataPromise().then(function() { /* use global */ data })
它只是getData().then(function(data) { … })
。
为了进一步改进模式,你可能想隐藏一个闭包范围内的dataPromise
,并且注意当getData
需要一个参数(比如url)时你将需要查找不同的promise。
为了这个任务,我创build了一个名为defer-cache-service的服务,它删除了所有这些锅炉板代码。 它写在Typescript,但你可以抓住编译的js文件。 Github 源代码 。
例:
function loadCached() { return deferCacheService.getDeferred('cacke.key1', function () { return $http.get("data.json"); }); }
并消费
loadCached().then(function(data) { //... });
一个重要的事情要注意,如果让我们说两个或两个以上的部分调用相同的loadDataPromise,并在同一时间,你必须添加此检查
if (defer && defer.promise.$$state.status === 0) { return defer.promise; }
否则你会重复调用后端。