Skip to content

Instantly share code, notes, and snippets.

@russellbeattie
Last active November 5, 2015 06:26
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save russellbeattie/a36b13efaab4f8396f9e to your computer and use it in GitHub Desktop.
Save russellbeattie/a36b13efaab4f8396f9e to your computer and use it in GitHub Desktop.
Clean version of Flux Dispatcher
/**
* Copyright (c) 2014-2015, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in
* https://github.com/facebook/flux/blob/master/LICENSE. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
define(function (require) {
"use strict";
var Dispatcher = {
callbacks: {},
isDispatching: false,
isHandled: {},
isPending: {},
pendingAction: null,
lastID: 1,
register: function (callback) {
var id = 'ID_' + this.lastID++;
this.callbacks[id] = callback;
return id;
},
unregister: function (id) {
if (!this.callbacks[id]) {
throw new Error('Dispatcher.unregister(...): ' + id + ' does not map to a registered callback. ');
}
delete this.callbacks[id];
},
waitFor: function (ids) {
if (!this.isDispatching) {
throw new Error('Dispatcher.waitFor(...): Must be invoked while dispatching.');
}
for (var ii = 0; ii < ids.length; ii++) {
var id = ids[ii];
if (this.isPending[id]) {
if (!this.isHandled[id]) {
throw new Error('Dispatcher.waitFor(...): Circular dependency detected while waiting for ' + id);
}
continue;
}
if (!this.callbacks[id]) {
throw new Error('Dispatcher.waitFor(...): ' + id + ' does not map to a registered callback. ');
}
this.invokeCallback(id);
}
},
dispatch: function (action) {
if (this.isDispatching) {
throw new Error('Dispatch.dispatch(...): Cannot dispatch in the middle of a dispatch.');
}
this.startDispatching(action);
try {
for (var id in this.callbacks) {
if (this.isPending[id]) {
continue;
}
this.invokeCallback(id);
}
} finally {
this.stopDispatching();
}
},
invokeCallback: function (id) {
this.isPending[id] = true;
this.callbacks[id](this.pendingAction);
this.isHandled[id] = true;
},
startDispatching: function (action) {
for (var id in this.callbacks) {
this.isPending[id] = false;
this.isHandled[id] = false;
}
this.pendingAction = action;
this.isDispatching = true;
},
stopDispatching: function () {
delete this.pendingAction;
this.isDispatching = false;
}
};
return Dispatcher; // singleton
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment