为了账号安全,请及时绑定邮箱和手机立即绑定

在AngularJS服务中缓存promise对象

在AngularJS服务中缓存promise对象

慕的地6264312 2019-08-05 15:22:49
在AngularJS服务中缓存promise对象我想使用Promises在AngularJS中实现动态加载静态资源。问题:我在页面上有几个组件可能(或不是,取决于哪些显示,因此是动态的)需要从服务器获取静态资源。加载后,可以在整个应用程序生命周期内进行缓存。我已经实现了这个机制,但我是Angular和Promises的新手,我想确保这是一个正确的解决方案\方法。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()的所有下一次调用都会获得第一个承诺。它似乎适用于进展中的请求或前一段时间已经完成的请求。但缓存Promises是一个很好的解决方案吗?
查看完整描述

3 回答

?
富国沪深

TA贡献1790条经验 获得超9个赞

这是正确的方法吗?

是。对返回的函数使用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)时需要查找不同的promise 。


查看完整回答
反对 回复 2019-08-05
?
绝地无双

TA贡献1946条经验 获得超4个赞

为此,我创建了名为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;}

否则你将对后端进行重复调用。


查看完整回答
反对 回复 2019-08-05
?
浮云间

TA贡献1829条经验 获得超4个赞

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


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调用都具有完全相同的值(除了第一次)


查看完整回答
反对 回复 2019-08-05
  • 3 回答
  • 0 关注
  • 575 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信