Flux без кэширования данных?

Почти все примеры Flux включают кеширование данных на стороне клиента, однако я не думаю, что смогу сделать это для многих своих приложений.

В системе, которую я думаю об использовании React/Flux, один пользователь может иметь сотни тысяч основных данных, которые мы храним (и 1 запись, вероятно, имеет не менее 75 свойств данных). Кэширование такого большого количества данных на стороне клиента кажется плохой идеей и, вероятно, усложняет ситуацию.

Если бы я не использовал Flux, у меня была бы просто система, подобная ORM, которая может взаимодействовать с REST API, и в этом случае запрос типа userRepository.getById(123) всегда попадал бы в API, независимо от того, запрашивал ли я эти данные на последней странице. Моя идея состоит в том, чтобы в магазине были эти методы.

Считает ли Flux плохим тот факт, что если я буду запрашивать данные, он всегда попадет в API и никогда не извлечет данные из экземпляра локального кеша? Могу ли я использовать Flux таким образом, чтобы большинство запросов на получение данных всегда попадали в API?


person ryanzec    schedule 09.12.2014    source источник


Ответы (2)


Самое близкое, что вы можете сделать без кэширования, — это сбросить любое состояние хранилища на null или [] при поступлении действия, запрашивающего новые данные. Если вы сделаете это, вы должны создать событие изменения, иначе вы предложить условия гонки.

В качестве альтернативы потоку вы можете просто использовать промисы и простой миксин с API для изменения состояния. Например, с синей птицей:

var promiseStateMixin = {
  thenSetState: function(updates, initialUpdates){
    // promisify setState
    var setState = this.setState.bind(this);
    var setStateP = function(changes){
        return new Promise(function(resolve){
            setState(changes, resolve);
        });
    };

    // if we have initial updates, apply them and ensure the state change happens
    return Promise.resolve(initialUpdates ? setStateP(initialUpdates) : null)
      // wait for our main updates to resolve
      .then(Promise.params(updates))
      // apply our unwrapped updates
      .then(function(updates){
          return setStateP(updates);
      }).bind(this); 
  }
};

И в ваших компонентах:

handleRefreshClick: function(){
  this.thenSetState(
      // users is Promise<User[]>
      {users: Api.Users.getAll(), loading: false}, 

      // we can't do our own setState due to unlikely race conditions
      // instead we supply our own here, but don't worry, the
      // getAll request is already running
      // this argument is optional
      {users: [], loading: true}
   ).catch(function(error){
      // the rejection reason for our getUsers promise 
      // `this` is our component instance here
      error.users 
   });
}

Конечно, это не мешает вам использовать поток, когда и где это имеет смысл в вашем приложении. Например, react-router используется во многих реактивных проектах и ​​внутри использует поток. React и связанные с ним библиотеки/шаблоны предназначены только для помощи там, где это необходимо, и никогда не контролируют то, как вы пишете каждый компонент.

person Brigand    schedule 09.12.2014

Я думаю, что самое большое преимущество использования Flux в этой ситуации заключается в том, что остальной части вашего приложения не нужно заботиться о том, чтобы данные никогда не кэшировались, или о том, что вы используете определенную систему ORM. Что касается ваших компонентов, данные хранятся в хранилищах, и данные можно изменить с помощью действий. Ваши действия или хранилища могут выбирать: всегда обращаться к API за данными или кэшировать некоторые части локально, но вы все равно выигрываете, инкапсулируя эту магию.

person Micah Condon    schedule 09.12.2014
comment
Ну, проблема в том, что хранилища из того, что я прочитал, должны 1. генерировать только одно событие, которое было изменено, и 2. что генерация не должна передавать с ним никаких данных, вы должны вызывать хранилище в обратном вызове, чтобы получить данные. Если у меня есть страница, скажем, панель инструментов для системы управления проектами, где у меня есть 3 отдельных запроса на список задач, каждый из которых фильтруется по-разному. Если у меня есть только 1 хранилище задач, как я могу узнать, когда какой запрос завершился, и если я не кэширую данные, как мне его получить? - person ryanzec; 09.12.2014
comment
в итоге это выглядит примерно так: при первом вызове store.getIssues, если в хранилище нет данных, он инициирует запрос API и возвращает пустой результат. Как только запрос API завершается асинхронно, действие отправляется, и хранилище обновляется и генерирует событие изменения. Итак, теперь первоначальный вызывающий объект снова вызывает store.getIssues и на этот раз получает данные вместо пустого списка. - person Micah Condon; 09.12.2014
comment
вам все равно придется решать, кэшировать ли какие-либо данные и как сделать этот кеш недействительным - вы можете кэшировать некоторые данные, и если хранилище получает запрос на устаревшие данные, хранилище возвращает устаревшие данные и вызывает API для обновить себя (которое затем отправляет действие и вызывает другое событие изменения хранилища) - person Micah Condon; 09.12.2014