Skip to content

Instantly share code, notes, and snippets.

@esnunes
Last active August 29, 2015 14:05
Show Gist options
  • Save esnunes/11981c66716ca7f7a369 to your computer and use it in GitHub Desktop.
Save esnunes/11981c66716ca7f7a369 to your computer and use it in GitHub Desktop.
react flux dispatcher promises with circular dependency detection
var Promise = require('es6-promise').Promise;
var handlerA = function () {
return waitFor([handlerB])
.then(function () {
console.log('handlerA');
});
};
var handlerB = function () {
return waitFor([handlerD])
.then(function () {
console.log('handlerB');
});
};
var handlerC = function () {
console.log('handlerC');
return new Promise(function (resolve, reject) {
setTimeout(resolve, 2000);
});
};
var handlerD = function () {
return waitFor([handlerC]) // replace handlerC to handlerA to force circular dependency
.then(function () {
console.log('handlerD');
});
};
var state = {};
var master = [handlerA, handlerB, handlerC, handlerD];
var waitFor = function (handlers) {
return execute(handlers);
};
var execute = function (handlers) {
return new Promise(function (resolve, reject) {
var queue = handlers.slice();
var finished = function () {
resolve();
};
var run = function () {
if (queue.length === 0) return finished();
var handler = queue.shift();
var pos = master.indexOf(handler);
if (pos === -1 && state[handler] === 'done') return run();
if (pos === -1) return reject(new Error('circular dependency'));
master.splice(pos, 1);
Promise.resolve()
.then(handler)
.then(updateState.bind(null, handler))
.then(run, reject);
};
run();
});
};
var updateState = function (handler) {
state[handler] = 'done';
};
var success = function () {
console.log('success');
};
var fail = function () {
console.log('fail', arguments);
};
execute(master)
.then(success, fail);
@fisherwebdev
Copy link

Works well, as far as I can tell! Really impressed that you were able to figure this out -- I was unable to find this solution back in December/January when I was first working on open sourcing Flux.

I do wonder about the efficiency of this approach, however. I put a console.log at the top of run() and saw it getting called many more times than the number of handlers. In what way is this solution a better approach than the synchronous dispatcher?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment