javascript - 在 Aurelia 中使用 Promise 进行数据检索和缓存

标签 javascript aurelia es6-promise

我创建了一个从 API 获取数据集的数据服务,但我希望它首先在本地缓存并检查相同的数据是否已经可用(不用担心过时的数据因素......我'接下来会处理这个问题)。这是我的代码:

getData(url, use_cache = true) {
  // Http Fetch Client to retreive data (GET)
  let cache_index = this.cache.findIndex(r => { return r.url === url; });
  if ((use_cache) && (cache_index > -1) && (this.cache[cache_index].data.length)) {
    // Use cached data (available)
    console.log("Found cached data!", this.cache[cache_index].data);
    //
    // I think this next line is the problem... need to return a promise???
    //
    return this.cache[cache_index].data;
  } else {
    console.log("Retrieving records from " + url);
    return this.httpClient.fetch(url, {
      credentials: 'include'
    }).then(response => {
      // Old statement was simple...
      // return response.json();

      // New method seems to be working because it's saving the data into the cache
      return response.json().then(result => {
        this.cache.push({'url': url, 'data': result});
        // Not sure why I need this next line, but I do.
        return result;
      });
    });
  }
}

第一次检索数据效果很好,即使在第二次调用时我也可以看到(从控制台日志)它找到了正确的缓存数据,但我收到了一个我认为与此相关的错误 promise ,这还不属于我的专业领域。

错误消息: 错误 [app-router] TypeError:this.core.getData(...).then 不是函数

这个错误实际上是在我的 View 模型的调用者中,如下所示:

getAccounts() {
  this.core.getData('/accounting/account/all').then(response => {
    this.accounts = response;
  });
}

我猜想,因为当数据被缓存时,它实际上不是返回 promise ,而是返回数据,并且原始数据上没有 .then 方法。

我怀疑我需要创建一个假 promise (即使它不是异步事务)以在缓存数据时返回,或者改进我从数据服务调用此方法(或返回数据)的方式。

关于如何解决当前的问题有什么想法吗?关于整个主题与 Aurelia 相关的任何免费建议吗?

最佳答案

I guess since when the data is cached, instead of returning a promise it's actually returning the data, and there's no .then method on the raw data.

是的。

I suspect I need to either create a fake promise (even though it's not an async transaction) to return when the data is cached

可能(使用Promise.resolve),但不行。

…or improve the way I'm calling this method from my data service (or returning the data).

不,您肯定不需要它。

相反,有一个更简单的解决方案:缓存 Promise 对象本身,并从该 url 的每次调用中返回相同的 Promise!

getData(url, use_cache = true) {
  // Http Fetch Client to retreive data (GET)
  if (use_cache && url in this.cache)
    return this.cache[url];
  else
    return this.cache[url] = this.httpClient.fetch(url, {
      credentials: 'include'
    }).then(response => response.json());
}

这还有一个额外的好处,即您永远不会对同一资源有两个并行请求 - 请求本身会被缓存,而不仅仅是到达的结果。唯一的缺点是您还会缓存错误,如果您想避免这种情况并重试后续调用,那么您必须在拒绝时删除缓存。

关于javascript - 在 Aurelia 中使用 Promise 进行数据检索和缓存,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42277847/

相关文章:

javascript - Promise/A+ 规范第 2.2.4 条背后的意图是什么?

javascript - 从 promise Angular 2内部设置类的全局变量

javascript - 如何进行递归 Promise 调用以作为 Javascript 中 reduce 的返回值?

javascript - Jquery克隆表单值并替换表单字段id

aurelia - 重定向到 aurelia 中当前范围之外定义的路由

javascript - 从 Aurelia View 模型中的 canActivate 导航

javascript - 服务器和客户端验证器 - 库

javascript - 将动态 JSON 数据嵌套到 Extjs 模型

javascript - 函数表达式与函数声明 : return value

javascript - d3.scan() 中的比较器如何工作?