Skip to content

Commit de1f783

Browse files
committed
Update todomvc dispatcher to match docs, add AppDispatcher test
1 parent f12a376 commit de1f783

File tree

3 files changed

+90
-29
lines changed

3 files changed

+90
-29
lines changed

examples/todomvc-flux/js/dispatcher/Dispatcher.js

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -27,28 +27,6 @@ var merge = require('react/lib/merge');
2727
var _callbacks = [];
2828
var _promises = [];
2929

30-
/**
31-
* Add a promise to the queue of callback invocation promises.
32-
* @param {function} callback The Store's registered callback.
33-
* @param {object} payload The data from the Action.
34-
*/
35-
var _addPromise = function(callback, payload) {
36-
_promises.push(new Promise(function(resolve, reject) {
37-
if (callback(payload)) {
38-
resolve(payload);
39-
} else {
40-
reject(new Error('Dispatcher callback unsuccessful'));
41-
}
42-
}));
43-
};
44-
45-
/**
46-
* Empty the queue of callback invocation promises.
47-
*/
48-
var _clearPromises = function() {
49-
_promises = [];
50-
};
51-
5230
var Dispatcher = function() {};
5331
Dispatcher.prototype = merge(Dispatcher.prototype, {
5432

@@ -67,10 +45,26 @@ Dispatcher.prototype = merge(Dispatcher.prototype, {
6745
* @param {object} payload The data from the action.
6846
*/
6947
dispatch: function(payload) {
70-
_callbacks.forEach(function(callback) {
71-
_addPromise(callback, payload);
48+
// First create array of promises for callbacks to reference.
49+
var _resolves = [];
50+
var _rejects = [];
51+
_promises = _callbacks.map(function(_, i) {
52+
return new Promise(function(resolve, reject) {
53+
_resolves[i] = resolve;
54+
_rejects[i] = reject;
55+
});
56+
});
57+
// Dispatch to callbacks and resolve/reject promises.
58+
_callbacks.forEach(function(callback, i) {
59+
// Callback can return an obj, to resolve, or a promise, to chain.
60+
// See waitFor() for why this might be useful.
61+
Promise.resolve(callback(payload)).then(function() {
62+
_resolves[i](payload);
63+
}, function() {
64+
_rejects[i](new Error('Dispatcher callback unsuccessful'));
65+
});
7266
});
73-
Promise.all(_promises).then(_clearPromises);
67+
_promises = [];
7468
},
7569

7670
/**
@@ -108,10 +102,10 @@ Dispatcher.prototype = merge(Dispatcher.prototype, {
108102
* A more robust Dispatcher would issue a warning in this scenario.
109103
*/
110104
waitFor: function(/*array*/ promiseIndexes, /*function*/ callback) {
111-
var selectedPromises = _promises.filter(function(/*object*/ _, /*number*/ j) {
112-
return promiseIndexes.indexOf(j) !== -1;
105+
var selectedPromises = promiseIndexes.map(function(index) {
106+
return _promises[index];
113107
});
114-
Promise.all(selectedPromises).then(callback);
108+
return Promise.all(selectedPromises).then(callback);
115109
}
116110

117111
});
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
"use strict";
2+
3+
jest.autoMockOff();
4+
5+
describe('AppDispatcher', function() {
6+
var AppDispatcher;
7+
8+
beforeEach(function() {
9+
AppDispatcher = require('../AppDispatcher.js');
10+
});
11+
12+
it('sends actions to subscribers', function() {
13+
var listener = jest.genMockFunction();
14+
AppDispatcher.register(listener);
15+
16+
var payload = {};
17+
AppDispatcher.dispatch(payload);
18+
expect(listener.mock.calls.length).toBe(1);
19+
expect(listener.mock.calls[0][0]).toBe(payload);
20+
});
21+
22+
it.only('waits with chained dependencies properly', function() {
23+
var payload = {};
24+
25+
var listener1Done = false;
26+
var listener1 = function(pl) {
27+
return AppDispatcher.waitFor([index2], function() {
28+
// Second and third listeners should have now been called
29+
expect(listener2Done).toBe(true);
30+
expect(listener3Done).toBe(true);
31+
listener1Done = true;
32+
});
33+
};
34+
var index1 = AppDispatcher.register(listener1);
35+
36+
var listener2Done = false;
37+
var listener2 = function(pl) {
38+
return AppDispatcher.waitFor([index3], function() {
39+
expect(listener3Done).toBe(true);
40+
listener2Done = true;
41+
});
42+
};
43+
var index2 = AppDispatcher.register(listener2);
44+
45+
var listener3Done = false;
46+
var listener3 = function(pl) {
47+
listener3Done = true;
48+
return true;
49+
};
50+
var index3 = AppDispatcher.register(listener3);
51+
52+
runs(function() {
53+
AppDispatcher.dispatch(payload);
54+
});
55+
56+
waitsFor(function() {
57+
return listener1Done;
58+
}, "Not all subscribers were properly called", 500);
59+
60+
runs(function() {
61+
expect(listener1Done).toBe(true);
62+
expect(listener2Done).toBe(true);
63+
expect(listener3Done).toBe(true);
64+
});
65+
});
66+
});

examples/todomvc-flux/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
"reactify": "~0.4.0",
1414
"statics": "~0.1.0",
1515
"uglify-js": "~2.4.13",
16-
"watchify": "~0.4.1"
16+
"watchify": "~0.4.1",
17+
"jest-cli": "~0.1.5"
1718
},
1819
"scripts": {
1920
"start": "STATIC_ROOT=./static watchify -o js/bundle.js -v -d .",

0 commit comments

Comments
 (0)