When using RefluxJS stores with asynchronous actions, you can easily get race conditions between your actions.
Brief Description of the Problem
For example, our store is in state X. Asynchronous action A is called from X and before its completion, another asynchronous action B is also called from X. From here, no matter what action ends first, it goes wrong.
- B ends first with state Y1, A ends last and overwrites state Y1 with Y2.
- A first ends with state Y2, B overwrites Y2 with Y1.
Desired behavior:
A B
X -> Y -> Z
Where B is not based on X, but on Y and leads to a consistent state of Z instead of two actions based on the same state, which leads to an inconsistent state:
A
X -> Y1 .--> Y2
\ /
'----'
B
, Node, , .
var Q = require('q');
var Reflux = require('reflux');
var RefluxPromise = require('reflux-promise');
Reflux.use(RefluxPromise(Q.Promise));
var AsyncActions = Reflux.createActions({
'add': { asyncResult: true }
});
var AsyncStore = Reflux.createStore({
init: function () {
this.counter = 0;
AsyncActions.add.listenAndPromise(this.onAdd, this);
},
onAdd: function(n, delay) {
var that = this;
return apiAdd(this.counter, n, delay)
.then(function (newCounter) {
that.counter = newCounter;
that.trigger(that.counter);
});
}
});
function apiAdd(counter, n, delay) {
var result = Q.defer();
setTimeout(function () {
result.resolve(counter + n);
}, delay);
return result.promise;
}
AsyncStore.listen(console.log.bind(undefined, 'Triggered'));
AsyncActions.add(3, 1000);
AsyncActions.add(100, 1);
package.json
{
"dependencies": {
"q": "^1.3.0",
"reflux": "^0.3",
"reflux-promise": "^1"
}
}
, RefluxJS , . . - ( B A), , A , B - ?
, RefluxJS, .
( , Reflux) ? ?