如何使用Flux管理异步存储操作?

时间:2014-05-13 15:51:44

标签: reactjs reactjs-flux

在关于Flux架构的Facebook讨论中,Jing提到at 12:17调度员强制执行在商店完全处理当前操作之前不能调度任何操作。

  

https://img.youtube.com/vi/nYkdrAPrdcw/0.jpg

     

这里的调度员是强制执行没有级联效应的主要部分;一旦一个动作进入商店,你就不能再放一个,直到商店完全处理完毕。

那么,我的问题是,您如何正确处理可能从存储中启动的长时间运行的异步操作(例如,Ajax请求,或处理其他一些外部异步API) - 阻止完成的任何东西操作调度(例如,等待使用Ajax请求的结果来解析promise)可能会阻止用户调度UI生成的操作。

2 个答案:

答案 0 :(得分:30)

根据我的理解,依赖Ajax等的异步操作不应阻止将动作分发给所有订阅者。

您将对用户操作执行单独操作,例如TodoMVC示例中的TODO_UPDATE_TEXT以及服务器返回时调用的操作,例如TODO_UPDATE_TEXT_COMPLETED(或者更多内容)类似TODO_UPDATE_COMPLETED的泛型,包含最新属性的新副本。)

如果您希望进行乐观更新以立即向用户显示其更改的效果,您可以立即更新商店以响应用户操作(然后在服务器返回权威数据时再次更新)。如果要在服务器上等待,则可以让商店仅更新自身以响应服务器触发的操作。

答案 1 :(得分:2)

查看Sophie在this fluxxor example中解释异步数据处理的实现。 一个负面的观点是,遵循这种方法,每个用户交互都需要三个动作(触发,成功和失败),但可能并非所有用户交互都需要这种乐观的方法。

重要的部分在于行动:

loadBuzz: function() {
  this.dispatch(constants.LOAD_BUZZ);

  BuzzwordClient.load(function(words) {
    this.dispatch(constants.LOAD_BUZZ_SUCCESS, {words: words});
    }.bind(this), function(error) {
    this.dispatch(constants.LOAD_BUZZ_FAIL, {error: error});
    }.bind(this));
  },

BinaryMuse(fluxxor creator)调度LOAD_BUZZ操作,然后使用成功和失败函数触发异步请求,其中调度成功或失败操作。 商店可以收听LOAD_BUZZ操作以进行乐观更新或显示svg加载图标,然后收听成功和错误操作以获得成功或错误的最终通知(并在商店中保存BUZZWORD)。

onLoadBuzz: function() {
  this.loading = true;
  this.emit("change");
},

onLoadBuzzSuccess: function(payload) {
  this.loading = false;
  this.error = null;

  this.words = payload.words.reduce(function(acc, word) {
    var clientId = _.uniqueId();
    acc[clientId] = {id: clientId, word: word, status: "OK"};
    return acc;
  }, {});
  this.emit("change");
},

我认为像Sophie一样,ajax请求不应该阻止调度操作,因为这更像是对服务器的同步请求,并且页面的响应性会受到影响。