一尘不染

在AngularJS服务中缓存一个Promise对象

angularjs

我想使用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的好解决方案吗?


阅读 265

收藏
2020-07-04

共1个答案

一尘不染

这是正确的方法吗?

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

这是正确的解决方案吗?

否。全局data变量及其解决方案undefined并不是promise的工作原理。相反,用结果实现承诺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。

2020-07-04