yoshuawuyts / barracks

:mountain_railway: action dispatcher for unidirectional data flows
MIT License
177 stars 22 forks source link

Make it smart #7

Closed yoshuawuyts closed 10 years ago

yoshuawuyts commented 10 years ago

The dispatcher example looks quite good, let's see if we can copy some methods out of it.

https://github.com/facebook/flux/blob/master/src/Dispatcher.js#L239

yoshuawuyts commented 10 years ago

The usage of waitFor is as follows:

/**
 * When the callback to update `CountryStore` is registered, we save a reference
 * to the returned token. Using this token with `waitFor()`, we can guarantee
 * that `CountryStore` is updated before the callback that updates `CityStore`
 * needs to query its data.
 */
 CityStore.dispatchToken = flightDispatcher.register(function(payload) {
     if (payload.actionType === 'country-update') {
       // `CountryStore.country` may not be updated.
       flightDispatcher.waitFor([CountryStore.dispatchToken]);
       // `CountryStore.country` is now guaranteed to be updated.

       // Select the default city for the new country
       CityStore.city = getDefaultCityForCountry(CountryStore.country);
     }
   });

/**
 * The usage of `waitFor()` can be chained, for example:
 */

   FlightPriceStore.dispatchToken =
     flightDispatcher.register(function(payload) {
       switch (payload.actionType) {
         case 'country-update':
           flightDispatcher.waitFor([CityStore.dispatchToken]);
           FlightPriceStore.price =
             getFlightPriceStore(CountryStore.country, CityStore.city);
           break;

         case 'city-update':
           FlightPriceStore.price =
             FlightPriceStore(CountryStore.country, CityStore.city);
           break;
     }
   });

/**
 * The `country-update` payload will be guaranteed to invoke the stores'
 * registered callbacks in order: `CountryStore`, `CityStore`, then
 * `FlightPriceStore`.
 */
yoshuawuyts commented 10 years ago

We could possibly leverage generators to do this. E.g.

var store = require('../store/myStore');

dispatcher({
  user: {
    get: function() {
      yield this.update();
      yield myStore.get();
    },
    update: function() {
      myStore.update();
    }
  }
})
yoshuawuyts commented 10 years ago

async should work also: https://www.npmjs.org/package/async

var store = require('../store/myStore');

dispatcher({
  user: {
    get: function() {
      async.series([
        this.update(),
        myStore.get()
      ]);
    },
    update: function() {
      myStore.update();
    }
  }
})
yoshuawuyts commented 10 years ago

Though all of these solutions fall outside the object, we should probably just use the initial solution.