我想实现在使用承诺AngularJS静态资源的动态加载。 问题:我有可能(或不取决于其上显示,从而动态)页面上的情侣组件需要从服务器获取静态资源。 一旦加载,它可以被缓存为整个应用程序生命。
我已经实现了这一机制,但我新的角度和承诺,我要确保,如果这是一个正确的解决方案\办法。
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;
}
所以,只有一个请求,以及所有未来调用loadDataPromise()返回第一个做出承诺。 这似乎为要求的进展状况或一个已经完成了前一段时间的工作。
但它是一个很好的解决方案,以高速缓存的承诺?
这是正确的做法?
是。 使用memoisation上返回的承诺的常用技术的功能,以避免异步(和通常是昂贵的)任务的重复执行。 该承诺使缓存容易的,因为一个并不需要持续和完成作业,他们都表示对结果值(下同)的承诺来区分。
这是正确的解决方案?
第这种全球data
变量和与分辨率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)。
对于这个任务,我创建的服务称为延迟,缓存服务,删除所有该锅炉板代码。 它创作的在打字稿,但你可以抓住编译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;
}
否则你会做重复调用后端。
这种设计的设计模式将缓存任何返回它第一次运行时,每次它再次调用时返回缓存的事情。
const asyncTask = (cache => { return function(){ // when called first time, put the promise in the "cache" variable if( !cache ){ cache = new Promise(function(resolve, reject){ setTimeout(() => { resolve('foo'); }, 2000); }); } return cache; } })(); asyncTask().then(console.log); asyncTask().then(console.log);
说明:
简单地返回功能(原来的异步函数),另一个自调用函数包住功能,包装功能的目的是提供一个局部变量封装范围cache
,使局部变量只是返回的函数中访问包装功能,并具有完全相同的值每一次asyncTask
被称为(除第一次外)