goatslacker / alt

Isomorphic flux implementation
http://alt.js.org/
3.45k stars 322 forks source link

Docs: please explain how waitFor() actually works #655

Closed rulatir closed 8 years ago

rulatir commented 8 years ago

The waitFor() example in the docs shows this code of an action handler that uses waitFor():

setFavorites(location) {
  this.waitFor(FavoritesStore);

  var favoritedLocations = FavoritesStore.getState().locations;

  this.resetAllFavorites();

  favoritedLocations.forEach((location) => {
    // find each location in the array
    for (var i = 0; i < this.locations.length; i += 1) {

      // set has_favorite to true
      if (this.locations[i].id === location.id) {
        this.locations[i].has_favorite = true;
        break;
      }
    }
  });
}

I don't understand how this is supposed to work. I don't see any async pattern used here; the code looks as if the this.waitFor() call would block while waiting for the other store to be "done", and this is plainly impossible. For all I know about async stuff in javascript, I would expect something like

this.waitFor(FavoritesStore).then(function(){/* work */});

but this is not what I see in the example.

The only other possibility I can imagine is that this.waitFor() throws an exception that is caught by alt, and the handler actually reschedules a "retry" of the setFavorites handler (which it knows was the one being called) until after the depended-on store is "done". If this is the case, it should be documented and explained.

jdlehman commented 8 years ago

waitFor is used to specify other stores that must be handled by the dispatcher before handling the dispatch in the current store. Since alt uses Facebook's Flux dispatcher to handle dispatching, waitFor is actually exposing the waitFor from Facebook's dispatcher. Facebook describes what this does and when it is needed in their docs here and here.

There is also a section on waitFor in alt's store docs, or on this page if you prefer the website docs.

I hope that helps.

druska commented 8 years ago

What waitFor does is actually quite simple. The function name makes it seem like it's doing some crazy async stuff, but it's not.

All waitFor does is run another store's action listener function, synchronously, if it hasn't been run before.

Here's a simple example:

class FooStore {
    @bind(Actions.Reset)
    onReset() {
        this.waitFor(BarStore)
        /**
         * This just ran BarStore's `onReset` function. It's somewhat equivalent
         * to just running: `BarStore.onReset()`, except the logic is now decoupled
         * because FooStore doens't need to know anything about BarStore's
         * listeners.
         */
        BarStore.getState().get('baz')
    }
}
jdlehman commented 8 years ago

Thanks for clarifying and adding the example @druska! I am going to close this issue since waitFor is documented in the docs, but as always feel free to open PRs adding to the documentation