当数据缓存在本地时,Reflux 避免每次都访问服务器

Reflux avoid hitting server every time, when data cached locally

我很好奇是否有任何约定的模式来检查数据是否已经加载到服务器之前。

假设我的动作是这样的:

Actions.loadRequest.preEmit = function () {
  $.get('/store/', function (data) {
      Actions.loadSuccess(data);
  }.bind(this));
}

这是从一个组件调用的,它只是说给我这个数据: 但如果该数据已经在商店中,我不想访问服务器。 我是否应该将检查商店的逻辑存储在组件中:

render: function () {
  var data = this.state.store.data;
  if (!data) {
    Actions.loadRequest();
  }

有没有更好的方法来解决这个问题?

在我的项目中,我为此使用 shouldEmit(参见 https://github.com/reflux/refluxjs#action-hooks)。我的代码中的一个示例:

var streamStore = Reflux.createStore({
    [...]
});

actions.loadStream.shouldEmit = function(streamId) {
    if(streamId in streamStore.data)
        return false;
    return true;
};

这与商店定义位于同一个文件中。我认为这在概念上是正确的方法,因为商店保存数据,所以商店应该负责拦截加载更多数据的请求并拒绝,就像它负责听取更多数据可用和更新的操作一样本身。

不幸的是,这不适用于您的示例,因为您将 AJAX 调用绑定到 preEmit,它在 shouldEmit 之前被调用。我建议重构以在正常的 listen 调用中进行 API 调用,如下所示:

Actions.loadRequest.listen(function () {
  $.get('/store/', function (data) {
      Actions.loadSuccess(data);
  }.bind(this));
});

这节省了 preEmit 用于需要在发出操作之前重写操作参数的罕见情况。我确实在我的代码中使用了这种模式,例如在加载第二页结果时,它依赖于第一页附带的 next 令牌,因此在商店中。但在 "action triggered, so make a request" 的一般简单情况下,使用 listen 更有意义,因为你可以添加 preEmitshouldEmit 以获得更高级的行为,比如你想要的缓存。

Reflux 还有一个辅助函数 listenAndPromise,它进一步简化了 "action fired, make AJAX call, then fire another action when it's done" 的常见用例。你的例子可以变成:

Actions.loadRequest.listenAndPromise(function () {
    return $.get('/store/');
});    

有关如何设置的更多信息,请参阅文档的这一部分:https://github.com/reflux/refluxjs#asynchronous-actions