Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/442.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/24.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服务中缓存承诺对象_Javascript_Angularjs_Promise_Angular Promise - Fatal编程技术网

Javascript 在AngularJS服务中缓存承诺对象

Javascript 在AngularJS服务中缓存承诺对象,javascript,angularjs,promise,angular-promise,Javascript,Angularjs,Promise,Angular Promise,我想使用Promissions在AngularJS中实现静态资源的动态加载。问题是:我在页面上有两个组件,它们可能(或不,取决于显示的内容,因此是动态的)需要从服务器获取静态资源。一旦加载,它可以在整个应用程序生命周期中缓存 我已经实现了这个机制,但我对角度和承诺还不熟悉,我想确定这是否是一个正确的解决方案\方法 var data = null; var deferredLoadData = null; function loadDataPromise() { if (deferredLo

我想使用Promissions在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()的所有调用都会返回第一个发出的承诺。它似乎在为正在进行的或已经完成了一段时间的请求而工作

但这是缓存承诺的好办法吗

这是正确的方法吗

对。使用返回的on函数承诺了一种避免重复执行异步(通常是昂贵的)任务的通用技术。这个承诺使缓存变得容易,因为不需要区分正在进行的操作和已完成的操作,它们都表示为结果值的(相同)承诺

这是正确的解决方案吗

不可以。全局
数据
变量和
未定义的分辨率
不是承诺的工作方式。相反,用结果
数据
来履行承诺!它还使编码更加容易:

var dataPromise = null;

function getData() {
    if (dataPromise == null)
        dataPromise = $http.get("data.json").then(function (res) {
           return res.data;
        });
    return dataPromise;
}
然后,它不是
loadDataPromise()。然后(function(){/*use global*/data})
而是
getData()。然后(function(data){…})


为了进一步改进模式,您可能希望在闭包范围中隐藏
dataPromise
,并注意,当
getData
获取参数(如url)时,您将需要查找不同的承诺。

为此任务,我创建了一个名为“延迟缓存服务”的服务,该服务将删除所有这些代码。它是用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;
}

否则,您将重复调用后端。

此设计模式将缓存第一次运行时返回的内容,并在每次再次调用时返回缓存的内容

const asyncTask=(缓存=>{
返回函数(){
//第一次调用时,将承诺放在“cache”变量中
如果(!缓存){
缓存=新承诺(函数(解析、拒绝){
设置超时(()=>{
决议(“foo”);
}, 2000);
});
}
返回缓存;
}
})();
asyncTask().then(console.log);

asyncTask().then(console.log)为什么不使用$cacheFactory?这难道不会给整个模块访问缓存带来更大的灵活性吗?@Darryl:对不起,我对Angular不太了解,我的答案只是基于承诺。@Darryl:我想主要的区别在于使用$cacheFactory可以缓存服务调用的结果,而使用“dataPromise”可以缓存承诺本身。第二种方法是,如果您调用服务两次,而第一个调用尚未返回,则不会触发第二个调用,并且当第一个调用返回时,两个承诺都已解决。在某些情况下,这是一个很大的优势。您在末尾为我节省了大量冗余和错误的代码。这一行不正确:
return delferredloaddata.resolve()。您只需
deferredLoadData.resolve()
延迟加载数据.拒绝()
return
语句使整个承诺返回
未定义的
@arcol-你说得对。这没有道理。事实上,它没有任何作用。(但它也不会破坏任何东西,因为没有使用链条)