Stop Trying to Catch Me

http://jlongster.com/Stop-Trying-to-Catch-Me

Promises are broken
Break on exception is permanently broken now, and we have to go through all sorts of contortions and backflips to get back to reasonable debugging environment. All because it wraps code in try/catch by default.

async/await
A lot of people are extremely excited about it, and honestly I don't get the excitement. Async functions are only pretty generators with promises. I just don't understand why everyone is so excited about a simple syntactic improvement.

// generators
var asyncFunction = Task(function*() {
  var result = yield fetch(url);
  return process(result);
}):

// async/await
async function asyncFunction() {
  var result = await fetch(url);
  return process(result);
}

Taming the Asynchronous Beast with CSP Channels in JavaScript

http://jlongster.com/Taming-the-Asynchronous-Beast-with-CSP-in-JavaScript

Callbacks are a dumb simple way for passing single values around asynchronously, and promises are a more refined solution to the same problem. Event emitters and streams allow asynchronous handling of multiple values. FRP is a different approach which tackles streams and events more elegantly, but isn't as good at asynchronous coordination.

CSP has been highly influential in Go and recently Clojure embraced it as well with core.async.

becoming quite popular (and validated)

Typically channels are useful for coordinating truly concurrent tasks that might run at the same time on separate threads. They are actually just as useful in a single-threaded environment because they solve a more general problem of coordinating anything asynchronous, which is everything in JavaScript.

I do have one issue with how errors are handled in promises: because it captures any error from a handler, you need to mark the end of a promise chain (with something like done()) or else it will suppress errors.

Error handling in CSP is definitely more manual
By default syntax/null/etc errors are simply thrown and not gobbled up.

In my opinion, anything that deals with asynchronous behavior and doesn't natively embrace generators is broken

cross-compile generators until they are implemented

promiseReturningFunction().then(function(value) {
  return value * 2;
});

spawn(function*() {
  return (yield promiseReturningFunction()) * 2;
});

go(function*() {
  return (yield take(channelReturningFunction())) * 2;
});

Channels are marginally better than promises with generators for single-value asynchronous coordination, but the best part is that you can do all sorts of more complex workflows that also relegate the need for streams and event-based systems.

Generators are coming to JavaScript and allow us to suspend and resume functions.

Using generators, the js-csp project has been able to faithfully port Clojure's core.async to JavaScript.

Principles of CSP:

  • Processes are spawned with go, and channels are created with chan.
  • Processes are completely unaware of each other but talk through channels.
  • Use take and put to operate on channels within a process. take gets a value and blocks if one isn't available. put puts a value on a channel and blocks if a process isn't available to take it.
// Flux version
var Cart = React.createClass({
  componentDidMount:function(){
    appStore.addChangeListener(this._onStuffChange)
  },
  // rest redacted
});

// Reflux version
var Cart = React.createClass({
  mixins: [Reflux.ListenerMixin],
  componentDidMount: function() {
    this.listenTo(appStore, this._onStuffChange);
  },
  // rest redacted
});
ListenerMixin = {
    componentWillMount: function() {
        this.subscriptions = [];
    },
    listenTo: function(listenable, callback, defaultCallback) {
        var unsubscribe = listenable.listen(callback, this);
        this.subscriptions.push(unsubscribe);
        _.handleDefaultCallback(this, listenable, defaultCallback);
    },
    componentWillUnmount: function() {
        this.subscriptions.forEach(function(unsubscribe) {
            unsubscribe();
        });
        this.subscriptions = [];
    }
};

Container Components — Medium

https://medium.com/@learnreact/container-components-c0e67432e005

container component pattern.
Jason Bonta

A container does data fetching and then renders its corresponding (= same name without Container) sub-component.

Divide components into two categories
Fat = smart = stateful / skinny = dumb = pure

Dumb

  • no deps (no store, no actions)
  • allows containment via this.props.children
  • everything (data, cbs) from props
  • has CSS
  • no state (or very small)
  • eg. Page, Sidebar, Story, UserInfo, List.

Smart

  • wrappers
  • hold state from Flux stores
  • pass data to dump
  • never have CSS
  • call flux actions
  • do not emit DOM
  • UserPage, FollowersSidebar, StoryContainer, FollowedUserList

Dump component for Style guide