【问题标题】:Using a promise in Aurelia for data retrieval and caching在 Aurelia 中使用 Promise 进行数据检索和缓存
【发布时间】:2017-02-16 23:24:30
【问题描述】:

我创建了一个从 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;
      });
    });
  }
}

第一次检索数据可以正常工作,即使在第二次调用时,我也可以(从控制台日志)看到它找到了正确的缓存数据,但我收到了一个我认为与承诺,这还不属于我的专业领域。

错误信息: ERROR [app-router] TypeError: this.core.getData(...).then is not a function

这个错误实际上是在我的视图模型的调用者中,它看起来像这样:

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

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

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

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

【问题讨论】:

    标签: javascript aurelia es6-promise


    【解决方案1】:

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

    是的。

    我怀疑我需要创建一个假承诺(即使它不是异步事务)以在缓存数据时返回

    可能(使用Promise.resolve),但没有。

    …或改进我从数据服务调用此方法(或返回数据)的方式。

    不,你肯定不需要那个。

    相反,有一个更简单的解决方案:缓存 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());
    }
    

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

    【讨论】:

    • 我不得不说这是一个了不起的解决方案!如果我可以投票 10 次,我会的!
    猜你喜欢
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-01
    • 2020-09-28
    • 2015-11-22
    • 1970-01-01
    • 2013-10-28
    相关资源
    最近更新 更多