Search code examples
javascriptmobxmobx-state-tree

Only one MobX-State-Tree flow active at a time


I have a MobX-State-Tree (MST) store with an action that is a flow that fetches some items asynchronously. This action can be called from several places in the app, sometimes even simultaneously, but I only want one flow to be active at a time.

Is there any way in MST to return the currently active flow if there is one, or create a new one if there isn't?

Example

const Thing = types.model({
  id: types.identifier,
  name: types.string,
});

const ThingStore = types
  .model({
    things: types.array(Thing),
  })
  .actions((self) => ({
    // This action will create a new flow every time it is called.
    fetchThings: flow(function* () {
      const things = yield fetchThings();

      self.things = things;
    }),
  }));

Solution

  • You can create a piece of volatile state that keeps a reference to the promise that is returned when calling a flow. If a flow is already active we return this promise. If not, we create a new flow and return that.

    Example

    const Thing = types.model({
      id: types.identifier,
      name: types.string,
    });
    
    const ThingStore = types
      .model({
        things: types.array(Thing),
      })
      .actions((self) => {
        let fetchThingsPromise = null;
        const fetchThings = flow(function* () {
          try {
            const things = yield fetchThings();
    
            self.things = things;
          } finally {
            fetchThingsPromise = null;
          }
        });
    
        return {
          fetchThings: function () {
            if (fetchThingsPromise) return fetchThingsPromise;
    
            fetchThingsPromise = fetchThings.apply(null, arguments);
            return fetchThingsPromise;
          },
        };
      });